Repository: dtolnay/syn
Pull request #1362 (2023-02-06 00:58:44)

Reorder GenericParams so lifetimes come before types
This matches the order in the Rust Reference. It also matches the order these parameters are *required* to appear in source code &mdash; makes sense.

https://doc.rust-lang.org/nightly/reference/items/generics.html


Patch:
diff --git a/src/gen/clone.rs b/src/gen/clone.rs
index 9d38c531..23ecbe2f 100644
--- a/src/gen/clone.rs
+++ b/src/gen/clone.rs
@@ -955,8 +955,8 @@ impl Clone for GenericArgument {
 impl Clone for GenericParam {
     fn clone(&self) -> Self {
         match self {
-            GenericParam::Type(v0) => GenericParam::Type(v0.clone()),
             GenericParam::Lifetime(v0) => GenericParam::Lifetime(v0.clone()),
+            GenericParam::Type(v0) => GenericParam::Type(v0.clone()),
             GenericParam::Const(v0) => GenericParam::Const(v0.clone()),
         }
     }
diff --git a/src/gen/debug.rs b/src/gen/debug.rs
index 6bc422d3..1b17f647 100644
--- a/src/gen/debug.rs
+++ b/src/gen/debug.rs
@@ -1392,13 +1392,13 @@ impl Debug for GenericParam {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         formatter.write_str("GenericParam::")?;
         match self {
-            GenericParam::Type(v0) => {
-                let mut formatter = formatter.debug_tuple("Type");
+            GenericParam::Lifetime(v0) => {
+                let mut formatter = formatter.debug_tuple("Lifetime");
                 formatter.field(v0);
                 formatter.finish()
             }
-            GenericParam::Lifetime(v0) => {
-                let mut formatter = formatter.debug_tuple("Lifetime");
+            GenericParam::Type(v0) => {
+                let mut formatter = formatter.debug_tuple("Type");
                 formatter.field(v0);
                 formatter.finish()
             }
diff --git a/src/gen/eq.rs b/src/gen/eq.rs
index 8e2f6f93..ead36435 100644
--- a/src/gen/eq.rs
+++ b/src/gen/eq.rs
@@ -938,10 +938,10 @@ impl Eq for GenericParam {}
 impl PartialEq for GenericParam {
     fn eq(&self, other: &Self) -> bool {
         match (self, other) {
-            (GenericParam::Type(self0), GenericParam::Type(other0)) => self0 == other0,
             (GenericParam::Lifetime(self0), GenericParam::Lifetime(other0)) => {
                 self0 == other0
             }
+            (GenericParam::Type(self0), GenericParam::Type(other0)) => self0 == other0,
             (GenericParam::Const(self0), GenericParam::Const(other0)) => self0 == other0,
             _ => false,
         }
diff --git a/src/gen/fold.rs b/src/gen/fold.rs
index 54c2a29a..6596f383 100644
--- a/src/gen/fold.rs
+++ b/src/gen/fold.rs
@@ -1818,12 +1818,12 @@ where
     F: Fold + ?Sized,
 {
     match node {
-        GenericParam::Type(_binding_0) => {
-            GenericParam::Type(f.fold_type_param(_binding_0))
-        }
         GenericParam::Lifetime(_binding_0) => {
             GenericParam::Lifetime(f.fold_lifetime_param(_binding_0))
         }
+        GenericParam::Type(_binding_0) => {
+            GenericParam::Type(f.fold_type_param(_binding_0))
+        }
         GenericParam::Const(_binding_0) => {
             GenericParam::Const(f.fold_const_param(_binding_0))
         }
diff --git a/src/gen/hash.rs b/src/gen/hash.rs
index b56a2cf4..b8f07118 100644
--- a/src/gen/hash.rs
+++ b/src/gen/hash.rs
@@ -1250,11 +1250,11 @@ impl Hash for GenericParam {
         H: Hasher,
     {
         match self {
-            GenericParam::Type(v0) => {
+            GenericParam::Lifetime(v0) => {
                 state.write_u8(0u8);
                 v0.hash(state);
             }
-            GenericParam::Lifetime(v0) => {
+            GenericParam::Type(v0) => {
                 state.write_u8(1u8);
                 v0.hash(state);
             }
diff --git a/src/gen/visit.rs b/src/gen/visit.rs
index cc3e702b..8903a051 100644
--- a/src/gen/visit.rs
+++ b/src/gen/visit.rs
@@ -2017,12 +2017,12 @@ where
     V: Visit<'ast> + ?Sized,
 {
     match node {
-        GenericParam::Type(_binding_0) => {
-            v.visit_type_param(_binding_0);
-        }
         GenericParam::Lifetime(_binding_0) => {
             v.visit_lifetime_param(_binding_0);
         }
+        GenericParam::Type(_binding_0) => {
+            v.visit_type_param(_binding_0);
+        }
         GenericParam::Const(_binding_0) => {
             v.visit_const_param(_binding_0);
         }
diff --git a/src/gen/visit_mut.rs b/src/gen/visit_mut.rs
index 7b4179a9..d6877956 100644
--- a/src/gen/visit_mut.rs
+++ b/src/gen/visit_mut.rs
@@ -2018,12 +2018,12 @@ where
     V: VisitMut + ?Sized,
 {
     match node {
-        GenericParam::Type(_binding_0) => {
-            v.visit_type_param_mut(_binding_0);
-        }
         GenericParam::Lifetime(_binding_0) => {
             v.visit_lifetime_param_mut(_binding_0);
         }
+        GenericParam::Type(_binding_0) => {
+            v.visit_type_param_mut(_binding_0);
+        }
         GenericParam::Const(_binding_0) => {
             v.visit_const_param_mut(_binding_0);
         }
diff --git a/src/generics.rs b/src/generics.rs
index 5359ef98..e12bff12 100644
--- a/src/generics.rs
+++ b/src/generics.rs
@@ -36,38 +36,38 @@ ast_enum_of_structs! {
     /// [syntax tree enum]: Expr#syntax-tree-enums
     #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
     pub enum GenericParam {
+        /// A lifetime parameter: `'a: 'b + 'c + 'd`.
+        Lifetime(LifetimeParam),
+
         /// A generic type parameter: `T: Into<String>`.
         Type(TypeParam),
 
-        /// A lifetime definition: `'a: 'b + 'c + 'd`.
-        Lifetime(LifetimeParam),
-
         /// A const generic parameter: `const LENGTH: usize`.
         Const(ConstParam),
     }
 }
 
 ast_struct! {
-    /// A generic type parameter: `T: Into<String>`.
+    /// A lifetime definition: `'a: 'b + 'c + 'd`.
     #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
-    pub struct TypeParam {
+    pub struct LifetimeParam {
         pub attrs: Vec<Attribute>,
-        pub ident: Ident,
+        pub lifetime: Lifetime,
         pub colon_token: Option<Token![:]>,
-        pub bounds: Punctuated<TypeParamBound, Token![+]>,
-        pub eq_token: Option<Token![=]>,
-        pub default: Option<Type>,
+        pub bounds: Punctuated<Lifetime, Token![+]>,
     }
 }
 
 ast_struct! {
-    /// A lifetime definition: `'a: 'b + 'c + 'd`.
+    /// A generic type parameter: `T: Into<String>`.
     #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
-    pub struct LifetimeParam {
+    pub struct TypeParam {
         pub attrs: Vec<Attribute>,
-        pub lifetime: Lifetime,
+        pub ident: Ident,
         pub colon_token: Option<Token![:]>,
-        pub bounds: Punctuated<Lifetime, Token![+]>,
+        pub bounds: Punctuated<TypeParamBound, Token![+]>,
+        pub eq_token: Option<Token![=]>,
+        pub default: Option<Type>,
     }
 }
 
@@ -100,45 +100,45 @@ impl Generics {
     /// Returns an
     /// <code
     ///   style="padding-right:0;">Iterator&lt;Item = &amp;</code><a
-    ///   href="struct.TypeParam.html"><code
-    ///   style="padding-left:0;padding-right:0;">TypeParam</code></a><code
+    ///   href="struct.LifetimeParam.html"><code
+    ///   style="padding-left:0;padding-right:0;">LifetimeParam</code></a><code
     ///   style="padding-left:0;">&gt;</code>
-    /// over the type parameters in `self.params`.
-    pub fn type_params(&self) -> TypeParams {
-        TypeParams(self.params.iter())
+    /// over the lifetime parameters in `self.params`.
+    pub fn lifetimes(&self) -> Lifetimes {
+        Lifetimes(self.params.iter())
     }
 
     /// Returns an
     /// <code
     ///   style="padding-right:0;">Iterator&lt;Item = &amp;mut </code><a
-    ///   href="struct.TypeParam.html"><code
-    ///   style="padding-left:0;padding-right:0;">TypeParam</code></a><code
+    ///   href="struct.LifetimeParam.html"><code
+    ///   style="padding-left:0;padding-right:0;">LifetimeParam</code></a><code
     ///   style="padding-left:0;">&gt;</code>
-    /// over the type parameters in `self.params`.
-    pub fn type_params_mut(&mut self) -> TypeParamsMut {
-        TypeParamsMut(self.params.iter_mut())
+    /// over the lifetime parameters in `self.params`.
+    pub fn lifetimes_mut(&mut self) -> LifetimesMut {
+        LifetimesMut(self.params.iter_mut())
     }
 
     /// Returns an
     /// <code
     ///   style="padding-right:0;">Iterator&lt;Item = &amp;</code><a
-    ///   href="struct.LifetimeParam.html"><code
-    ///   style="padding-left:0;padding-right:0;">LifetimeParam</code></a><code
+    ///   href="struct.TypeParam.html"><code
+    ///   style="padding-left:0;padding-right:0;">TypeParam</code></a><code
     ///   style="padding-left:0;">&gt;</code>
-    /// over the lifetime parameters in `self.params`.
-    pub fn lifetimes(&self) -> Lifetimes {
-        Lifetimes(self.params.iter())
+    /// over the type parameters in `self.params`.
+    pub fn type_params(&self) -> TypeParams {
+        TypeParams(self.params.iter())
     }
 
     /// Returns an
     /// <code
     ///   style="padding-right:0;">Iterator&lt;Item = &amp;mut </code><a
-    ///   href="struct.LifetimeParam.html"><code
-    ///   style="padding-left:0;padding-right:0;">LifetimeParam</code></a><code
+    ///   href="struct.TypeParam.html"><code
+    ///   style="padding-left:0;padding-right:0;">TypeParam</code></a><code
     ///   style="padding-left:0;">&gt;</code>
-    /// over the lifetime parameters in `self.params`.
-    pub fn lifetimes_mut(&mut self) -> LifetimesMut {
-        LifetimesMut(self.params.iter_mut())
+    /// over the type parameters in `self.params`.
+    pub fn type_params_mut(&mut self) -> TypeParamsMut {
+        TypeParamsMut(self.params.iter_mut())
     }
 
     /// Returns an
@@ -172,72 +172,72 @@ impl Generics {
     }
 }
 
-pub struct TypeParams<'a>(Iter<'a, GenericParam>);
+pub struct Lifetimes<'a>(Iter<'a, GenericParam>);
 
-impl<'a> Iterator for TypeParams<'a> {
-    type Item = &'a TypeParam;
+impl<'a> Iterator for Lifetimes<'a> {
+    type Item = &'a LifetimeParam;
 
     fn next(&mut self) -> Option<Self::Item> {
         let next = match self.0.next() {
             Some(item) => item,
             None => return None,
         };
-        if let GenericParam::Type(type_param) = next {
-            Some(type_param)
+        if let GenericParam::Lifetime(lifetime) = next {
+            Some(lifetime)
         } else {
             self.next()
         }
     }
 }
 
-pub struct TypeParamsMut<'a>(IterMut<'a, GenericParam>);
+pub struct LifetimesMut<'a>(IterMut<'a, GenericParam>);
 
-impl<'a> Iterator for TypeParamsMut<'a> {
-    type Item = &'a mut TypeParam;
+impl<'a> Iterator for LifetimesMut<'a> {
+    type Item = &'a mut LifetimeParam;
 
     fn next(&mut self) -> Option<Self::Item> {
         let next = match self.0.next() {
             Some(item) => item,
             None => return None,
         };
-        if let GenericParam::Type(type_param) = next {
-            Some(type_param)
+        if let GenericParam::Lifetime(lifetime) = next {
+            Some(lifetime)
         } else {
             self.next()
         }
     }
 }
 
-pub struct Lifetimes<'a>(Iter<'a, GenericParam>);
+pub struct TypeParams<'a>(Iter<'a, GenericParam>);
 
-impl<'a> Iterator for Lifetimes<'a> {
-    type Item = &'a LifetimeParam;
+impl<'a> Iterator for TypeParams<'a> {
+    type Item = &'a TypeParam;
 
     fn next(&mut self) -> Option<Self::Item> {
         let next = match self.0.next() {
             Some(item) => item,
             None => return None,
         };
-        if let GenericParam::Lifetime(lifetime) = next {
-            Some(lifetime)
+        if let GenericParam::Type(type_param) = next {
+            Some(type_param)
         } else {
             self.next()
         }
     }
 }
 
-pub struct LifetimesMut<'a>(IterMut<'a, GenericParam>);
+pub struct TypeParamsMut<'a>(IterMut<'a, GenericParam>);
 
-impl<'a> Iterator for LifetimesMut<'a> {
-    type Item = &'a mut LifetimeParam;
+impl<'a> Iterator for TypeParamsMut<'a> {
+    type Item = &'a mut TypeParam;
 
     fn next(&mut self) -> Option<Self::Item> {
         let next = match self.0.next() {
             Some(item) => item,
             None => return None,
         };
-        if let GenericParam::Lifetime(lifetime) = next {
-            Some(lifetime)
+        if let GenericParam::Type(type_param) = next {
+            Some(type_param)
         } else {
             self.next()
         }
diff --git a/syn.json b/syn.json
index 04f668c1..a2526723 100644
--- a/syn.json
+++ b/syn.json
@@ -2360,14 +2360,14 @@
         ]
       },
       "variants": {
-        "Type": [
+        "Lifetime": [
           {
-            "syn": "TypeParam"
+            "syn": "LifetimeParam"
           }
         ],
-        "Lifetime": [
+        "Type": [
           {
-            "syn": "LifetimeParam"
+            "syn": "TypeParam"
           }
         ],
         "Const": [


Test patch:
diff --git a/tests/debug/gen.rs b/tests/debug/gen.rs
index 0004a5ff..e0af0c79 100644
--- a/tests/debug/gen.rs
+++ b/tests/debug/gen.rs
@@ -2045,15 +2045,15 @@ impl Debug for Lite<syn::GenericArgument> {
 impl Debug for Lite<syn::GenericParam> {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         match &self.value {
-            syn::GenericParam::Type(_val) => {
-                formatter.write_str("GenericParam::Type")?;
+            syn::GenericParam::Lifetime(_val) => {
+                formatter.write_str("GenericParam::Lifetime")?;
                 formatter.write_str("(")?;
                 Debug::fmt(Lite(_val), formatter)?;
                 formatter.write_str(")")?;
                 Ok(())
             }
-            syn::GenericParam::Lifetime(_val) => {
-                formatter.write_str("GenericParam::Lifetime")?;
+            syn::GenericParam::Type(_val) => {
+                formatter.write_str("GenericParam::Type")?;
                 formatter.write_str("(")?;
                 Debug::fmt(Lite(_val), formatter)?;
                 formatter.write_str(")")?;