Update generic arguments to be stored similar to generic parameters
diff --git a/src/gen/fold.rs b/src/gen/fold.rs
index b6996f4..6b61ccc 100644
--- a/src/gen/fold.rs
+++ b/src/gen/fold.rs
@@ -204,6 +204,8 @@
# [ cfg ( feature = "full" ) ]
fn fold_foreign_item_type(&mut self, i: ForeignItemType) -> ForeignItemType { fold_foreign_item_type(self, i) }
+fn fold_generic_arg(&mut self, i: GenericArg) -> GenericArg { fold_generic_arg(self, i) }
+
fn fold_generic_param(&mut self, i: GenericParam) -> GenericParam { fold_generic_param(self, i) }
fn fold_generics(&mut self, i: Generics) -> Generics { fold_generics(self, i) }
@@ -428,9 +430,7 @@
AngleBracketedParameterData {
turbofish: _i . turbofish,
lt_token: _i . lt_token,
- lifetimes: _i . lifetimes,
- types: FoldHelper::lift(_i . types, |it| { _visitor.fold_type(it) }),
- bindings: FoldHelper::lift(_i . bindings, |it| { _visitor.fold_type_binding(it) }),
+ args: FoldHelper::lift(_i . args, |it| { _visitor.fold_generic_arg(it) }),
gt_token: _i . gt_token,
}
}
@@ -1452,6 +1452,27 @@
}
}
+pub fn fold_generic_arg<V: Folder + ?Sized>(_visitor: &mut V, _i: GenericArg) -> GenericArg {
+ use ::GenericArg::*;
+ match _i {
+ Lifetime(_binding_0, ) => {
+ Lifetime (
+ _binding_0,
+ )
+ }
+ Type(_binding_0, ) => {
+ Type (
+ _visitor.fold_type(_binding_0),
+ )
+ }
+ TypeBinding(_binding_0, ) => {
+ TypeBinding (
+ _visitor.fold_type_binding(_binding_0),
+ )
+ }
+ }
+}
+
pub fn fold_generic_param<V: Folder + ?Sized>(_visitor: &mut V, _i: GenericParam) -> GenericParam {
use ::GenericParam::*;
match _i {
diff --git a/src/gen/visit.rs b/src/gen/visit.rs
index ec40662..72f2861 100644
--- a/src/gen/visit.rs
+++ b/src/gen/visit.rs
@@ -177,6 +177,8 @@
# [ cfg ( feature = "full" ) ]
fn visit_foreign_item_type(&mut self, i: &'ast ForeignItemType) { visit_foreign_item_type(self, i) }
+fn visit_generic_arg(&mut self, i: &'ast GenericArg) { visit_generic_arg(self, i) }
+
fn visit_generic_param(&mut self, i: &'ast GenericParam) { visit_generic_param(self, i) }
fn visit_generics(&mut self, i: &'ast Generics) { visit_generics(self, i) }
@@ -396,9 +398,7 @@
pub fn visit_angle_bracketed_parameter_data<'ast, V: Visitor<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast AngleBracketedParameterData) {
// Skipped field _i . turbofish;
// Skipped field _i . lt_token;
- // Skipped field _i . lifetimes;
- for el in (_i . types).iter() { let it = el.item(); _visitor.visit_type(&it) };
- for el in (_i . bindings).iter() { let it = el.item(); _visitor.visit_type_binding(&it) };
+ for el in (_i . args).iter() { let it = el.item(); _visitor.visit_generic_arg(&it) };
// Skipped field _i . gt_token;
}
# [ cfg ( feature = "full" ) ]
@@ -1131,6 +1131,21 @@
// Skipped field _i . semi_token;
}
+pub fn visit_generic_arg<'ast, V: Visitor<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast GenericArg) {
+ use ::GenericArg::*;
+ match *_i {
+ Lifetime(ref _binding_0, ) => {
+ // Skipped field * _binding_0;
+ }
+ Type(ref _binding_0, ) => {
+ _visitor.visit_type(&* _binding_0);
+ }
+ TypeBinding(ref _binding_0, ) => {
+ _visitor.visit_type_binding(&* _binding_0);
+ }
+ }
+}
+
pub fn visit_generic_param<'ast, V: Visitor<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast GenericParam) {
use ::GenericParam::*;
match *_i {
diff --git a/src/gen/visit_mut.rs b/src/gen/visit_mut.rs
index 80329b0..2a4cb11 100644
--- a/src/gen/visit_mut.rs
+++ b/src/gen/visit_mut.rs
@@ -177,6 +177,8 @@
# [ cfg ( feature = "full" ) ]
fn visit_foreign_item_type_mut(&mut self, i: &mut ForeignItemType) { visit_foreign_item_type_mut(self, i) }
+fn visit_generic_arg_mut(&mut self, i: &mut GenericArg) { visit_generic_arg_mut(self, i) }
+
fn visit_generic_param_mut(&mut self, i: &mut GenericParam) { visit_generic_param_mut(self, i) }
fn visit_generics_mut(&mut self, i: &mut Generics) { visit_generics_mut(self, i) }
@@ -396,9 +398,7 @@
pub fn visit_angle_bracketed_parameter_data_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut AngleBracketedParameterData) {
// Skipped field _i . turbofish;
// Skipped field _i . lt_token;
- // Skipped field _i . lifetimes;
- for mut el in (_i . types).iter_mut() { let mut it = el.item_mut(); _visitor.visit_type_mut(&mut it) };
- for mut el in (_i . bindings).iter_mut() { let mut it = el.item_mut(); _visitor.visit_type_binding_mut(&mut it) };
+ for mut el in (_i . args).iter_mut() { let mut it = el.item_mut(); _visitor.visit_generic_arg_mut(&mut it) };
// Skipped field _i . gt_token;
}
# [ cfg ( feature = "full" ) ]
@@ -1131,6 +1131,21 @@
// Skipped field _i . semi_token;
}
+pub fn visit_generic_arg_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut GenericArg) {
+ use ::GenericArg::*;
+ match *_i {
+ Lifetime(ref mut _binding_0, ) => {
+ // Skipped field * _binding_0;
+ }
+ Type(ref mut _binding_0, ) => {
+ _visitor.visit_type_mut(&mut * _binding_0);
+ }
+ TypeBinding(ref mut _binding_0, ) => {
+ _visitor.visit_type_binding_mut(&mut * _binding_0);
+ }
+ }
+}
+
pub fn visit_generic_param_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut GenericParam) {
use ::GenericParam::*;
match *_i {
diff --git a/src/lib.rs b/src/lib.rs
index f88112d..bd59686 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -87,7 +87,7 @@
ReturnType, MutType, Mutability, ParenthesizedParameterData, Path,
PathParameters, PathSegment, PolyTraitRef, QSelf, Type, TypeBinding, Unsafety,
TypeSlice, TypeArray, TypePtr, TypeReference, TypeBareFn, TypeNever, TypeTup, TypePath,
- TypeTraitObject, TypeImplTrait, TypeParen, TypeInfer, TypeGroup};
+ TypeTraitObject, TypeImplTrait, TypeParen, TypeInfer, TypeGroup, GenericArg};
#[cfg(feature = "printing")]
pub use ty::PathTokens;
diff --git a/src/ty.rs b/src/ty.rs
index 009e081..77a43fb 100644
--- a/src/ty.rs
+++ b/src/ty.rs
@@ -184,28 +184,32 @@
pub fn is_empty(&self) -> bool {
match *self {
PathParameters::None => true,
- PathParameters::AngleBracketed(ref bracketed) => {
- bracketed.lifetimes.is_empty() && bracketed.types.is_empty() &&
- bracketed.bindings.is_empty()
- }
+ PathParameters::AngleBracketed(ref bracketed) => bracketed.args.is_empty(),
PathParameters::Parenthesized(_) => false,
}
}
}
+ast_enum! {
+ /// A individual generic argument, like `'a`, `T`, or `Item=T`.
+ pub enum GenericArg {
+ /// The lifetime parameters for this path segment.
+ Lifetime(Lifetime),
+ /// The type parameters for this path segment, if present.
+ Type(Type),
+ /// Bindings (equality constraints) on associated types, if present.
+ ///
+ /// E.g., `Foo<A=Bar>`.
+ TypeBinding(TypeBinding),
+ }
+}
+
ast_struct! {
/// A path like `Foo<'a, T>`
pub struct AngleBracketedParameterData {
pub turbofish: Option<Token![::]>,
pub lt_token: Token![<],
- /// The lifetime parameters for this path segment.
- pub lifetimes: Delimited<Lifetime, Token![,]>,
- /// The type parameters for this path segment, if present.
- pub types: Delimited<Type, Token![,]>,
- /// Bindings (equality constraints) on associated types, if present.
- ///
- /// E.g., `Foo<A=Bar>`.
- pub bindings: Delimited<TypeBinding, Token![,]>,
+ pub args: Delimited<GenericArg, Token![,]>,
pub gt_token: Token![>],
}
}
@@ -687,38 +691,39 @@
}
}
+ impl Synom for GenericArg {
+ named!(parse -> Self, alt!(
+ call!(ty_no_eq_after) => { GenericArg::Type }
+ |
+ syn!(Lifetime) => { GenericArg::Lifetime }
+ |
+ syn!(TypeBinding) => { GenericArg::TypeBinding }
+ ));
+ }
+
+ impl Synom for AngleBracketedParameterData {
+ named!(parse -> Self, do_parse!(
+ turbofish: option!(punct!(::)) >>
+ lt: punct!(<) >>
+ args: call!(Delimited::parse_terminated) >>
+ gt: punct!(>) >>
+ (AngleBracketedParameterData {
+ turbofish: turbofish,
+ lt_token: lt,
+ args: args,
+ gt_token: gt,
+ })
+ ));
+ }
+
impl Synom for PathSegment {
named!(parse -> Self, alt!(
do_parse!(
ident: syn!(Ident) >>
- turbofish: option!(punct!(::)) >>
- lt: punct!(<) >>
- lifetimes: call!(Delimited::parse_terminated) >>
- types: cond!(
- lifetimes.is_empty() || lifetimes.trailing_delim(),
- call!(Delimited::parse_terminated_with,
- ty_no_eq_after)
- ) >>
- bindings: cond!(
- match types {
- Some(ref t) => t.is_empty() || t.trailing_delim(),
- None => lifetimes.is_empty() || lifetimes.trailing_delim(),
- },
- call!(Delimited::parse_terminated)
- ) >>
- gt: punct!(>) >>
+ parameters: syn!(AngleBracketedParameterData) >>
(PathSegment {
ident: ident,
- parameters: PathParameters::AngleBracketed(
- AngleBracketedParameterData {
- turbofish: turbofish,
- lt_token: lt,
- lifetimes: lifetimes,
- types: types.unwrap_or_default(),
- bindings: bindings.unwrap_or_default(),
- gt_token: gt,
- }
- ),
+ parameters: PathParameters::AngleBracketed(parameters),
})
)
|
@@ -1018,27 +1023,21 @@
}
}
+ impl ToTokens for GenericArg {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ match *self {
+ GenericArg::Lifetime(ref lt) => lt.to_tokens(tokens),
+ GenericArg::Type(ref ty) => ty.to_tokens(tokens),
+ GenericArg::TypeBinding(ref tb) => tb.to_tokens(tokens),
+ }
+ }
+ }
+
impl ToTokens for AngleBracketedParameterData {
fn to_tokens(&self, tokens: &mut Tokens) {
self.turbofish.to_tokens(tokens);
self.lt_token.to_tokens(tokens);
- self.lifetimes.to_tokens(tokens);
- if !self.lifetimes.empty_or_trailing() && !self.types.is_empty() {
- <Token![,]>::default().to_tokens(tokens);
- }
- self.types.to_tokens(tokens);
- if (
- // If we have no trailing delimiter after a non-empty types list, or
- !self.types.empty_or_trailing() ||
- // If we have no trailing delimiter after a non-empty lifetimes
- // list before an empty types list, and
- (self.types.is_empty() && !self.lifetimes.empty_or_trailing())) &&
- // We have some bindings, then we need a comma.
- !self.bindings.is_empty()
- {
- <Token![,]>::default().to_tokens(tokens);
- }
- self.bindings.to_tokens(tokens);
+ self.args.to_tokens(tokens);
self.gt_token.to_tokens(tokens);
}
}