Merge pull request #261 from mystor/generic_arg_refactor
Generic arg refactor
diff --git a/src/gen/fold.rs b/src/gen/fold.rs
index b6996f4..ed7db7c 100644
--- a/src/gen/fold.rs
+++ b/src/gen/fold.rs
@@ -62,7 +62,7 @@
fn fold_abi_kind(&mut self, i: AbiKind) -> AbiKind { fold_abi_kind(self, i) }
-fn fold_angle_bracketed_parameter_data(&mut self, i: AngleBracketedParameterData) -> AngleBracketedParameterData { fold_angle_bracketed_parameter_data(self, i) }
+fn fold_angle_bracketed_generic_arguments(&mut self, i: AngleBracketedGenericArguments) -> AngleBracketedGenericArguments { fold_angle_bracketed_generic_arguments(self, i) }
# [ cfg ( feature = "full" ) ]
fn fold_arg_captured(&mut self, i: ArgCaptured) -> ArgCaptured { fold_arg_captured(self, i) }
# [ cfg ( feature = "full" ) ]
@@ -97,6 +97,8 @@
fn fold_bound_lifetimes(&mut self, i: BoundLifetimes) -> BoundLifetimes { fold_bound_lifetimes(self, i) }
# [ cfg ( feature = "full" ) ]
fn fold_capture_by(&mut self, i: CaptureBy) -> CaptureBy { fold_capture_by(self, i) }
+
+fn fold_const_param(&mut self, i: ConstParam) -> ConstParam { fold_const_param(self, i) }
# [ cfg ( feature = "full" ) ]
fn fold_constness(&mut self, i: Constness) -> Constness { fold_constness(self, i) }
# [ cfg ( feature = "full" ) ]
@@ -204,6 +206,8 @@
# [ cfg ( feature = "full" ) ]
fn fold_foreign_item_type(&mut self, i: ForeignItemType) -> ForeignItemType { fold_foreign_item_type(self, i) }
+fn fold_generic_argument(&mut self, i: GenericArgument) -> GenericArgument { fold_generic_argument(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) }
@@ -276,7 +280,7 @@
fn fold_nested_meta_item(&mut self, i: NestedMetaItem) -> NestedMetaItem { fold_nested_meta_item(self, i) }
-fn fold_parenthesized_parameter_data(&mut self, i: ParenthesizedParameterData) -> ParenthesizedParameterData { fold_parenthesized_parameter_data(self, i) }
+fn fold_parenthesized_generic_arguments(&mut self, i: ParenthesizedGenericArguments) -> ParenthesizedGenericArguments { fold_parenthesized_generic_arguments(self, i) }
# [ cfg ( feature = "full" ) ]
fn fold_pat(&mut self, i: Pat) -> Pat { fold_pat(self, i) }
# [ cfg ( feature = "full" ) ]
@@ -303,6 +307,8 @@
fn fold_pat_wild(&mut self, i: PatWild) -> PatWild { fold_pat_wild(self, i) }
fn fold_path(&mut self, i: Path) -> Path { fold_path(self, i) }
+
+fn fold_path_arguments(&mut self, i: PathArguments) -> PathArguments { fold_path_arguments(self, i) }
# [ cfg ( feature = "full" ) ]
fn fold_path_glob(&mut self, i: PathGlob) -> PathGlob { fold_path_glob(self, i) }
# [ cfg ( feature = "full" ) ]
@@ -310,8 +316,6 @@
# [ cfg ( feature = "full" ) ]
fn fold_path_list_item(&mut self, i: PathListItem) -> PathListItem { fold_path_list_item(self, i) }
-fn fold_path_parameters(&mut self, i: PathParameters) -> PathParameters { fold_path_parameters(self, i) }
-
fn fold_path_segment(&mut self, i: PathSegment) -> PathSegment { fold_path_segment(self, i) }
# [ cfg ( feature = "full" ) ]
fn fold_path_simple(&mut self, i: PathSimple) -> PathSimple { fold_path_simple(self, i) }
@@ -424,13 +428,11 @@
}
}
-pub fn fold_angle_bracketed_parameter_data<V: Folder + ?Sized>(_visitor: &mut V, _i: AngleBracketedParameterData) -> AngleBracketedParameterData {
- AngleBracketedParameterData {
+pub fn fold_angle_bracketed_generic_arguments<V: Folder + ?Sized>(_visitor: &mut V, _i: AngleBracketedGenericArguments) -> AngleBracketedGenericArguments {
+ AngleBracketedGenericArguments {
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_argument(it) }),
gt_token: _i . gt_token,
}
}
@@ -752,6 +754,18 @@
Ref => { Ref }
}
}
+
+pub fn fold_const_param<V: Folder + ?Sized>(_visitor: &mut V, _i: ConstParam) -> ConstParam {
+ ConstParam {
+ attrs: FoldHelper::lift(_i . attrs, |it| { _visitor.fold_attribute(it) }),
+ const_token: _i . const_token,
+ ident: _i . ident,
+ colon_token: _i . colon_token,
+ ty: _visitor.fold_type(_i . ty),
+ eq_token: _i . eq_token,
+ default: (_i . default).map(|it| { _visitor.fold_expr(it) }),
+ }
+}
# [ cfg ( feature = "full" ) ]
pub fn fold_constness<V: Folder + ?Sized>(_visitor: &mut V, _i: Constness) -> Constness {
use ::Constness::*;
@@ -1452,6 +1466,32 @@
}
}
+pub fn fold_generic_argument<V: Folder + ?Sized>(_visitor: &mut V, _i: GenericArgument) -> GenericArgument {
+ use ::GenericArgument::*;
+ 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),
+ )
+ }
+ Const(_binding_0, ) => {
+ Const (
+ full!(_visitor.fold_expr_block(_binding_0)),
+ )
+ }
+ }
+}
+
pub fn fold_generic_param<V: Folder + ?Sized>(_visitor: &mut V, _i: GenericParam) -> GenericParam {
use ::GenericParam::*;
match _i {
@@ -1465,6 +1505,11 @@
_visitor.fold_type_param(_binding_0),
)
}
+ Const(_binding_0, ) => {
+ Const (
+ _visitor.fold_const_param(_binding_0),
+ )
+ }
}
}
@@ -1964,8 +2009,8 @@
}
}
-pub fn fold_parenthesized_parameter_data<V: Folder + ?Sized>(_visitor: &mut V, _i: ParenthesizedParameterData) -> ParenthesizedParameterData {
- ParenthesizedParameterData {
+pub fn fold_parenthesized_generic_arguments<V: Folder + ?Sized>(_visitor: &mut V, _i: ParenthesizedGenericArguments) -> ParenthesizedGenericArguments {
+ ParenthesizedGenericArguments {
paren_token: _i . paren_token,
inputs: FoldHelper::lift(_i . inputs, |it| { _visitor.fold_type(it) }),
output: _visitor.fold_return_type(_i . output),
@@ -2132,6 +2177,23 @@
segments: FoldHelper::lift(_i . segments, |it| { _visitor.fold_path_segment(it) }),
}
}
+
+pub fn fold_path_arguments<V: Folder + ?Sized>(_visitor: &mut V, _i: PathArguments) -> PathArguments {
+ use ::PathArguments::*;
+ match _i {
+ None => { None }
+ AngleBracketed(_binding_0, ) => {
+ AngleBracketed (
+ _visitor.fold_angle_bracketed_generic_arguments(_binding_0),
+ )
+ }
+ Parenthesized(_binding_0, ) => {
+ Parenthesized (
+ _visitor.fold_parenthesized_generic_arguments(_binding_0),
+ )
+ }
+ }
+}
# [ cfg ( feature = "full" ) ]
pub fn fold_path_glob<V: Folder + ?Sized>(_visitor: &mut V, _i: PathGlob) -> PathGlob {
PathGlob {
@@ -2158,27 +2220,10 @@
}
}
-pub fn fold_path_parameters<V: Folder + ?Sized>(_visitor: &mut V, _i: PathParameters) -> PathParameters {
- use ::PathParameters::*;
- match _i {
- None => { None }
- AngleBracketed(_binding_0, ) => {
- AngleBracketed (
- _visitor.fold_angle_bracketed_parameter_data(_binding_0),
- )
- }
- Parenthesized(_binding_0, ) => {
- Parenthesized (
- _visitor.fold_parenthesized_parameter_data(_binding_0),
- )
- }
- }
-}
-
pub fn fold_path_segment<V: Folder + ?Sized>(_visitor: &mut V, _i: PathSegment) -> PathSegment {
PathSegment {
ident: _i . ident,
- parameters: _visitor.fold_path_parameters(_i . parameters),
+ arguments: _visitor.fold_path_arguments(_i . arguments),
}
}
# [ cfg ( feature = "full" ) ]
diff --git a/src/gen/visit.rs b/src/gen/visit.rs
index ec40662..b91254f 100644
--- a/src/gen/visit.rs
+++ b/src/gen/visit.rs
@@ -35,7 +35,7 @@
fn visit_abi_kind(&mut self, i: &'ast AbiKind) { visit_abi_kind(self, i) }
-fn visit_angle_bracketed_parameter_data(&mut self, i: &'ast AngleBracketedParameterData) { visit_angle_bracketed_parameter_data(self, i) }
+fn visit_angle_bracketed_generic_arguments(&mut self, i: &'ast AngleBracketedGenericArguments) { visit_angle_bracketed_generic_arguments(self, i) }
# [ cfg ( feature = "full" ) ]
fn visit_arg_captured(&mut self, i: &'ast ArgCaptured) { visit_arg_captured(self, i) }
# [ cfg ( feature = "full" ) ]
@@ -70,6 +70,8 @@
fn visit_bound_lifetimes(&mut self, i: &'ast BoundLifetimes) { visit_bound_lifetimes(self, i) }
# [ cfg ( feature = "full" ) ]
fn visit_capture_by(&mut self, i: &'ast CaptureBy) { visit_capture_by(self, i) }
+
+fn visit_const_param(&mut self, i: &'ast ConstParam) { visit_const_param(self, i) }
# [ cfg ( feature = "full" ) ]
fn visit_constness(&mut self, i: &'ast Constness) { visit_constness(self, i) }
# [ cfg ( feature = "full" ) ]
@@ -177,6 +179,8 @@
# [ cfg ( feature = "full" ) ]
fn visit_foreign_item_type(&mut self, i: &'ast ForeignItemType) { visit_foreign_item_type(self, i) }
+fn visit_generic_argument(&mut self, i: &'ast GenericArgument) { visit_generic_argument(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) }
@@ -249,7 +253,7 @@
fn visit_nested_meta_item(&mut self, i: &'ast NestedMetaItem) { visit_nested_meta_item(self, i) }
-fn visit_parenthesized_parameter_data(&mut self, i: &'ast ParenthesizedParameterData) { visit_parenthesized_parameter_data(self, i) }
+fn visit_parenthesized_generic_arguments(&mut self, i: &'ast ParenthesizedGenericArguments) { visit_parenthesized_generic_arguments(self, i) }
# [ cfg ( feature = "full" ) ]
fn visit_pat(&mut self, i: &'ast Pat) { visit_pat(self, i) }
# [ cfg ( feature = "full" ) ]
@@ -276,6 +280,8 @@
fn visit_pat_wild(&mut self, i: &'ast PatWild) { visit_pat_wild(self, i) }
fn visit_path(&mut self, i: &'ast Path) { visit_path(self, i) }
+
+fn visit_path_arguments(&mut self, i: &'ast PathArguments) { visit_path_arguments(self, i) }
# [ cfg ( feature = "full" ) ]
fn visit_path_glob(&mut self, i: &'ast PathGlob) { visit_path_glob(self, i) }
# [ cfg ( feature = "full" ) ]
@@ -283,8 +289,6 @@
# [ cfg ( feature = "full" ) ]
fn visit_path_list_item(&mut self, i: &'ast PathListItem) { visit_path_list_item(self, i) }
-fn visit_path_parameters(&mut self, i: &'ast PathParameters) { visit_path_parameters(self, i) }
-
fn visit_path_segment(&mut self, i: &'ast PathSegment) { visit_path_segment(self, i) }
# [ cfg ( feature = "full" ) ]
fn visit_path_simple(&mut self, i: &'ast PathSimple) { visit_path_simple(self, i) }
@@ -393,12 +397,10 @@
}
}
-pub fn visit_angle_bracketed_parameter_data<'ast, V: Visitor<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast AngleBracketedParameterData) {
+pub fn visit_angle_bracketed_generic_arguments<'ast, V: Visitor<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast AngleBracketedGenericArguments) {
// 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_argument(&it) };
// Skipped field _i . gt_token;
}
# [ cfg ( feature = "full" ) ]
@@ -625,6 +627,16 @@
Ref => { }
}
}
+
+pub fn visit_const_param<'ast, V: Visitor<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast ConstParam) {
+ for it in (_i . attrs).iter() { _visitor.visit_attribute(&it) };
+ // Skipped field _i . const_token;
+ // Skipped field _i . ident;
+ // Skipped field _i . colon_token;
+ _visitor.visit_type(&_i . ty);
+ // Skipped field _i . eq_token;
+ if let Some(ref it) = _i . default { _visitor.visit_expr(&* it) };
+}
# [ cfg ( feature = "full" ) ]
pub fn visit_constness<'ast, V: Visitor<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast Constness) {
use ::Constness::*;
@@ -1131,6 +1143,24 @@
// Skipped field _i . semi_token;
}
+pub fn visit_generic_argument<'ast, V: Visitor<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast GenericArgument) {
+ use ::GenericArgument::*;
+ 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);
+ }
+ Const(ref _binding_0, ) => {
+ full!(_visitor.visit_expr_block(&* _binding_0));
+ }
+ }
+}
+
pub fn visit_generic_param<'ast, V: Visitor<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast GenericParam) {
use ::GenericParam::*;
match *_i {
@@ -1140,6 +1170,9 @@
Type(ref _binding_0, ) => {
_visitor.visit_type_param(&* _binding_0);
}
+ Const(ref _binding_0, ) => {
+ _visitor.visit_const_param(&* _binding_0);
+ }
}
}
@@ -1527,7 +1560,7 @@
}
}
-pub fn visit_parenthesized_parameter_data<'ast, V: Visitor<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast ParenthesizedParameterData) {
+pub fn visit_parenthesized_generic_arguments<'ast, V: Visitor<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast ParenthesizedGenericArguments) {
// Skipped field _i . paren_token;
for el in (_i . inputs).iter() { let it = el.item(); _visitor.visit_type(&it) };
_visitor.visit_return_type(&_i . output);
@@ -1645,6 +1678,19 @@
// Skipped field _i . leading_colon;
for el in (_i . segments).iter() { let it = el.item(); _visitor.visit_path_segment(&it) };
}
+
+pub fn visit_path_arguments<'ast, V: Visitor<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast PathArguments) {
+ use ::PathArguments::*;
+ match *_i {
+ None => { }
+ AngleBracketed(ref _binding_0, ) => {
+ _visitor.visit_angle_bracketed_generic_arguments(&* _binding_0);
+ }
+ Parenthesized(ref _binding_0, ) => {
+ _visitor.visit_parenthesized_generic_arguments(&* _binding_0);
+ }
+ }
+}
# [ cfg ( feature = "full" ) ]
pub fn visit_path_glob<'ast, V: Visitor<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast PathGlob) {
_visitor.visit_path(&_i . path);
@@ -1665,22 +1711,9 @@
// Skipped field _i . as_token;
}
-pub fn visit_path_parameters<'ast, V: Visitor<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast PathParameters) {
- use ::PathParameters::*;
- match *_i {
- None => { }
- AngleBracketed(ref _binding_0, ) => {
- _visitor.visit_angle_bracketed_parameter_data(&* _binding_0);
- }
- Parenthesized(ref _binding_0, ) => {
- _visitor.visit_parenthesized_parameter_data(&* _binding_0);
- }
- }
-}
-
pub fn visit_path_segment<'ast, V: Visitor<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast PathSegment) {
// Skipped field _i . ident;
- _visitor.visit_path_parameters(&_i . parameters);
+ _visitor.visit_path_arguments(&_i . arguments);
}
# [ cfg ( feature = "full" ) ]
pub fn visit_path_simple<'ast, V: Visitor<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast PathSimple) {
diff --git a/src/gen/visit_mut.rs b/src/gen/visit_mut.rs
index 80329b0..5ff8dce 100644
--- a/src/gen/visit_mut.rs
+++ b/src/gen/visit_mut.rs
@@ -35,7 +35,7 @@
fn visit_abi_kind_mut(&mut self, i: &mut AbiKind) { visit_abi_kind_mut(self, i) }
-fn visit_angle_bracketed_parameter_data_mut(&mut self, i: &mut AngleBracketedParameterData) { visit_angle_bracketed_parameter_data_mut(self, i) }
+fn visit_angle_bracketed_generic_arguments_mut(&mut self, i: &mut AngleBracketedGenericArguments) { visit_angle_bracketed_generic_arguments_mut(self, i) }
# [ cfg ( feature = "full" ) ]
fn visit_arg_captured_mut(&mut self, i: &mut ArgCaptured) { visit_arg_captured_mut(self, i) }
# [ cfg ( feature = "full" ) ]
@@ -70,6 +70,8 @@
fn visit_bound_lifetimes_mut(&mut self, i: &mut BoundLifetimes) { visit_bound_lifetimes_mut(self, i) }
# [ cfg ( feature = "full" ) ]
fn visit_capture_by_mut(&mut self, i: &mut CaptureBy) { visit_capture_by_mut(self, i) }
+
+fn visit_const_param_mut(&mut self, i: &mut ConstParam) { visit_const_param_mut(self, i) }
# [ cfg ( feature = "full" ) ]
fn visit_constness_mut(&mut self, i: &mut Constness) { visit_constness_mut(self, i) }
# [ cfg ( feature = "full" ) ]
@@ -177,6 +179,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_argument_mut(&mut self, i: &mut GenericArgument) { visit_generic_argument_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) }
@@ -249,7 +253,7 @@
fn visit_nested_meta_item_mut(&mut self, i: &mut NestedMetaItem) { visit_nested_meta_item_mut(self, i) }
-fn visit_parenthesized_parameter_data_mut(&mut self, i: &mut ParenthesizedParameterData) { visit_parenthesized_parameter_data_mut(self, i) }
+fn visit_parenthesized_generic_arguments_mut(&mut self, i: &mut ParenthesizedGenericArguments) { visit_parenthesized_generic_arguments_mut(self, i) }
# [ cfg ( feature = "full" ) ]
fn visit_pat_mut(&mut self, i: &mut Pat) { visit_pat_mut(self, i) }
# [ cfg ( feature = "full" ) ]
@@ -276,6 +280,8 @@
fn visit_pat_wild_mut(&mut self, i: &mut PatWild) { visit_pat_wild_mut(self, i) }
fn visit_path_mut(&mut self, i: &mut Path) { visit_path_mut(self, i) }
+
+fn visit_path_arguments_mut(&mut self, i: &mut PathArguments) { visit_path_arguments_mut(self, i) }
# [ cfg ( feature = "full" ) ]
fn visit_path_glob_mut(&mut self, i: &mut PathGlob) { visit_path_glob_mut(self, i) }
# [ cfg ( feature = "full" ) ]
@@ -283,8 +289,6 @@
# [ cfg ( feature = "full" ) ]
fn visit_path_list_item_mut(&mut self, i: &mut PathListItem) { visit_path_list_item_mut(self, i) }
-fn visit_path_parameters_mut(&mut self, i: &mut PathParameters) { visit_path_parameters_mut(self, i) }
-
fn visit_path_segment_mut(&mut self, i: &mut PathSegment) { visit_path_segment_mut(self, i) }
# [ cfg ( feature = "full" ) ]
fn visit_path_simple_mut(&mut self, i: &mut PathSimple) { visit_path_simple_mut(self, i) }
@@ -393,12 +397,10 @@
}
}
-pub fn visit_angle_bracketed_parameter_data_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut AngleBracketedParameterData) {
+pub fn visit_angle_bracketed_generic_arguments_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut AngleBracketedGenericArguments) {
// 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_argument_mut(&mut it) };
// Skipped field _i . gt_token;
}
# [ cfg ( feature = "full" ) ]
@@ -625,6 +627,16 @@
Ref => { }
}
}
+
+pub fn visit_const_param_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut ConstParam) {
+ for mut it in (_i . attrs).iter_mut() { _visitor.visit_attribute_mut(&mut it) };
+ // Skipped field _i . const_token;
+ // Skipped field _i . ident;
+ // Skipped field _i . colon_token;
+ _visitor.visit_type_mut(&mut _i . ty);
+ // Skipped field _i . eq_token;
+ if let Some(ref mut it) = _i . default { _visitor.visit_expr_mut(&mut * it) };
+}
# [ cfg ( feature = "full" ) ]
pub fn visit_constness_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut Constness) {
use ::Constness::*;
@@ -1131,6 +1143,24 @@
// Skipped field _i . semi_token;
}
+pub fn visit_generic_argument_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut GenericArgument) {
+ use ::GenericArgument::*;
+ 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);
+ }
+ Const(ref mut _binding_0, ) => {
+ full!(_visitor.visit_expr_block_mut(&mut * _binding_0));
+ }
+ }
+}
+
pub fn visit_generic_param_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut GenericParam) {
use ::GenericParam::*;
match *_i {
@@ -1140,6 +1170,9 @@
Type(ref mut _binding_0, ) => {
_visitor.visit_type_param_mut(&mut * _binding_0);
}
+ Const(ref mut _binding_0, ) => {
+ _visitor.visit_const_param_mut(&mut * _binding_0);
+ }
}
}
@@ -1527,7 +1560,7 @@
}
}
-pub fn visit_parenthesized_parameter_data_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut ParenthesizedParameterData) {
+pub fn visit_parenthesized_generic_arguments_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut ParenthesizedGenericArguments) {
// Skipped field _i . paren_token;
for mut el in (_i . inputs).iter_mut() { let mut it = el.item_mut(); _visitor.visit_type_mut(&mut it) };
_visitor.visit_return_type_mut(&mut _i . output);
@@ -1645,6 +1678,19 @@
// Skipped field _i . leading_colon;
for mut el in (_i . segments).iter_mut() { let mut it = el.item_mut(); _visitor.visit_path_segment_mut(&mut it) };
}
+
+pub fn visit_path_arguments_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut PathArguments) {
+ use ::PathArguments::*;
+ match *_i {
+ None => { }
+ AngleBracketed(ref mut _binding_0, ) => {
+ _visitor.visit_angle_bracketed_generic_arguments_mut(&mut * _binding_0);
+ }
+ Parenthesized(ref mut _binding_0, ) => {
+ _visitor.visit_parenthesized_generic_arguments_mut(&mut * _binding_0);
+ }
+ }
+}
# [ cfg ( feature = "full" ) ]
pub fn visit_path_glob_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut PathGlob) {
_visitor.visit_path_mut(&mut _i . path);
@@ -1665,22 +1711,9 @@
// Skipped field _i . as_token;
}
-pub fn visit_path_parameters_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut PathParameters) {
- use ::PathParameters::*;
- match *_i {
- None => { }
- AngleBracketed(ref mut _binding_0, ) => {
- _visitor.visit_angle_bracketed_parameter_data_mut(&mut * _binding_0);
- }
- Parenthesized(ref mut _binding_0, ) => {
- _visitor.visit_parenthesized_parameter_data_mut(&mut * _binding_0);
- }
- }
-}
-
pub fn visit_path_segment_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut PathSegment) {
// Skipped field _i . ident;
- _visitor.visit_path_parameters_mut(&mut _i . parameters);
+ _visitor.visit_path_arguments_mut(&mut _i . arguments);
}
# [ cfg ( feature = "full" ) ]
pub fn visit_path_simple_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut PathSimple) {
diff --git a/src/generics.rs b/src/generics.rs
index 08dba39..9b21720 100644
--- a/src/generics.rs
+++ b/src/generics.rs
@@ -31,6 +31,16 @@
pub eq_token: Option<Token![=]>,
pub default: Option<Type>,
}),
+ /// A generic const parameter, e.g. `const LENGTH: usize`.
+ pub Const(ConstParam {
+ pub attrs: Vec<Attribute>,
+ pub const_token: Token![const],
+ pub ident: Ident,
+ pub colon_token: Token![:],
+ pub ty: Type,
+ pub eq_token: Option<Token![=]>,
+ pub default: Option<Expr>,
+ }),
}
}
@@ -301,10 +311,36 @@
));
fn description() -> Option<&'static str> {
- Some("type parameter buond")
+ Some("type parameter bound")
}
}
+ impl Synom for ConstParam {
+ named!(parse -> Self, do_parse!(
+ attrs: many0!(call!(Attribute::parse_outer)) >>
+ const_: keyword!(const) >>
+ ident: syn!(Ident) >>
+ colon: punct!(:) >>
+ ty: syn!(Type) >>
+ eq_def: option!(tuple!(punct!(=), syn!(Expr))) >>
+ ({
+ let (eq_token, default) = match eq_def {
+ Some((eq_token, default)) => (Some(eq_token), Some(default)),
+ None => (None, None),
+ };
+ ConstParam {
+ attrs: attrs,
+ const_token: const_,
+ ident: ident,
+ colon_token: colon,
+ ty: ty,
+ eq_token: eq_token,
+ default: default,
+ }
+ })
+ ));
+ }
+
impl Synom for WhereClause {
named!(parse -> Self, alt!(
do_parse!(
@@ -400,6 +436,14 @@
param.bounds.to_tokens(tokens);
}
}
+ GenericParam::Const(ref param) => {
+ // Leave off the const parameter defaults
+ tokens.append_all(param.attrs.outer());
+ param.const_token.to_tokens(tokens);
+ param.ident.to_tokens(tokens);
+ param.colon_token.to_tokens(tokens);
+ param.ty.to_tokens(tokens);
+ }
}
param.delimiter().to_tokens(tokens);
}
@@ -424,6 +468,10 @@
// Leave off the type parameter defaults
param.ident.to_tokens(tokens);
}
+ GenericParam::Const(ref param) => {
+ // Leave off the const parameter defaults
+ param.ident.to_tokens(tokens);
+ }
}
param.delimiter().to_tokens(tokens);
}
@@ -496,6 +544,20 @@
}
}
+ impl ToTokens for ConstParam {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ tokens.append_all(self.attrs.outer());
+ self.const_token.to_tokens(tokens);
+ self.ident.to_tokens(tokens);
+ self.colon_token.to_tokens(tokens);
+ self.ty.to_tokens(tokens);
+ if self.default.is_some() {
+ TokensOrDefault(&self.eq_token).to_tokens(tokens);
+ self.default.to_tokens(tokens);
+ }
+ }
+ }
+
impl ToTokens for WhereClause {
fn to_tokens(&self, tokens: &mut Tokens) {
if !self.predicates.is_empty() {
diff --git a/src/lib.rs b/src/lib.rs
index f88112d..92f3386 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -42,7 +42,7 @@
mod generics;
pub use generics::{Generics, GenericParam, LifetimeDef, TraitBoundModifier, TypeParam, TypeParamBound,
WhereBoundPredicate, WhereClause, WhereEqPredicate, WherePredicate,
- WhereRegionPredicate, BoundLifetimes};
+ WhereRegionPredicate, BoundLifetimes, ConstParam};
#[cfg(feature = "printing")]
pub use generics::{ImplGenerics, Turbofish, TypeGenerics};
@@ -83,11 +83,13 @@
pub use op::{BinOp, UnOp};
mod ty;
-pub use ty::{Abi, AbiKind, AngleBracketedParameterData, BareFnArg, BareFnArgName, BareFnType,
- 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};
+pub use ty::{Abi, AbiKind, AngleBracketedGenericArguments, BareFnArg,
+ BareFnArgName, BareFnType, ReturnType, MutType, Mutability,
+ ParenthesizedGenericArguments, Path, PathArguments, PathSegment,
+ PolyTraitRef, QSelf, Type, TypeBinding, Unsafety, TypeSlice,
+ TypeArray, TypePtr, TypeReference, TypeBareFn, TypeNever, TypeTup,
+ TypePath, TypeTraitObject, TypeImplTrait, TypeParen, TypeInfer,
+ TypeGroup, GenericArgument};
#[cfg(feature = "printing")]
pub use ty::PathTokens;
diff --git a/src/ty.rs b/src/ty.rs
index 009e081..085bf9c 100644
--- a/src/ty.rs
+++ b/src/ty.rs
@@ -45,7 +45,7 @@
/// A path (`module::module::...::Type`), optionally
/// "qualified", e.g. `<Vec<T> as SomeTrait>::SomeType`.
///
- /// Type parameters are stored in the Path itself
+ /// Type arguments are stored in the Path itself
pub Path(TypePath {
pub qself: Option<QSelf>,
pub path: Path,
@@ -141,12 +141,12 @@
pub struct PathSegment {
/// The identifier portion of this path segment.
pub ident: Ident,
- /// Type/lifetime parameters attached to this path. They come in
+ /// Type/lifetime arguments attached to this path. They come in
/// two flavors: `Path<A,B,C>` and `Path(A,B) -> C`. Note that
/// this is more than just simple syntactic sugar; the use of
/// parens affects the region binding rules, so we preserve the
/// distinction.
- pub parameters: PathParameters,
+ pub arguments: PathArguments,
}
}
@@ -156,56 +156,65 @@
fn from(ident: T) -> Self {
PathSegment {
ident: ident.into(),
- parameters: PathParameters::None,
+ arguments: PathArguments::None,
}
}
}
ast_enum! {
- /// Parameters of a path segment.
+ /// Arguments of a path segment.
///
/// E.g. `<A, B>` as in `Foo<A, B>` or `(A, B)` as in `Foo(A, B)`
- pub enum PathParameters {
+ pub enum PathArguments {
None,
/// The `<'a, A, B, C>` in `foo::bar::baz::<'a, A, B, C>`
- AngleBracketed(AngleBracketedParameterData),
+ AngleBracketed(AngleBracketedGenericArguments),
/// The `(A, B)` and `C` in `Foo(A, B) -> C`
- Parenthesized(ParenthesizedParameterData),
+ Parenthesized(ParenthesizedGenericArguments),
}
}
-impl Default for PathParameters {
+impl Default for PathArguments {
fn default() -> Self {
- PathParameters::None
+ PathArguments::None
}
}
-impl PathParameters {
+impl PathArguments {
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::Parenthesized(_) => false,
+ PathArguments::None => true,
+ PathArguments::AngleBracketed(ref bracketed) => bracketed.args.is_empty(),
+ PathArguments::Parenthesized(_) => false,
}
}
}
+ast_enum! {
+ /// A individual generic argument, like `'a`, `T`, or `Item=T`.
+ pub enum GenericArgument {
+ /// 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),
+ /// Const expression. Must be inside of a block.
+ ///
+ /// NOTE: Identity expressions are represented as Type arguments, as
+ /// they are indistinguishable syntactically.
+ Const(ExprBlock),
+ }
+}
+
ast_struct! {
/// A path like `Foo<'a, T>`
- pub struct AngleBracketedParameterData {
+ pub struct AngleBracketedGenericArguments {
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<GenericArgument, Token![,]>,
pub gt_token: Token![>],
}
}
@@ -222,7 +231,7 @@
ast_struct! {
/// A path like `Foo(A,B) -> C`
- pub struct ParenthesizedParameterData {
+ pub struct ParenthesizedGenericArguments {
pub paren_token: tokens::Paren,
/// `(A, B)`
pub inputs: Delimited<Type, Token![,]>,
@@ -511,8 +520,8 @@
named!(ty_path(allow_plus: bool) -> Type, do_parse!(
qpath: qpath >>
parenthesized: cond!(
- qpath.1.segments.get(qpath.1.segments.len() - 1).item().parameters.is_empty(),
- option!(syn!(ParenthesizedParameterData))
+ qpath.1.segments.get(qpath.1.segments.len() - 1).item().arguments.is_empty(),
+ option!(syn!(ParenthesizedGenericArguments))
) >>
// Only allow parsing additional bounds if allow_plus is true.
bounds: alt!(
@@ -526,9 +535,9 @@
({
let (qself, mut path) = qpath;
if let Some(Some(parenthesized)) = parenthesized {
- let parenthesized = PathParameters::Parenthesized(parenthesized);
+ let parenthesized = PathArguments::Parenthesized(parenthesized);
let len = path.segments.len();
- path.segments.get_mut(len - 1).item_mut().parameters = parenthesized;
+ path.segments.get_mut(len - 1).item_mut().arguments = parenthesized;
}
if bounds.is_empty() {
TypePath { qself: qself, path: path }.into()
@@ -596,11 +605,11 @@
map!(keyword!(self), |s| (None, s.into()))
));
- impl Synom for ParenthesizedParameterData {
+ impl Synom for ParenthesizedGenericArguments {
named!(parse -> Self, do_parse!(
data: parens!(call!(Delimited::parse_terminated)) >>
output: syn!(ReturnType) >>
- (ParenthesizedParameterData {
+ (ParenthesizedGenericArguments {
paren_token: data.1,
inputs: data.0,
output: output,
@@ -687,38 +696,53 @@
}
}
+ #[cfg(not(feature = "full"))]
+ impl Synom for GenericArgument {
+ named!(parse -> Self, alt!(
+ call!(ty_no_eq_after) => { GenericArgument::Type }
+ |
+ syn!(Lifetime) => { GenericArgument::Lifetime }
+ |
+ syn!(TypeBinding) => { GenericArgument::TypeBinding }
+ ));
+ }
+
+ #[cfg(feature = "full")]
+ impl Synom for GenericArgument {
+ named!(parse -> Self, alt!(
+ call!(ty_no_eq_after) => { GenericArgument::Type }
+ |
+ syn!(Lifetime) => { GenericArgument::Lifetime }
+ |
+ syn!(TypeBinding) => { GenericArgument::TypeBinding }
+ |
+ syn!(ExprBlock) => { GenericArgument::Const }
+ ));
+ }
+
+ impl Synom for AngleBracketedGenericArguments {
+ named!(parse -> Self, do_parse!(
+ turbofish: option!(punct!(::)) >>
+ lt: punct!(<) >>
+ args: call!(Delimited::parse_terminated) >>
+ gt: punct!(>) >>
+ (AngleBracketedGenericArguments {
+ 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!(>) >>
+ arguments: syn!(AngleBracketedGenericArguments) >>
(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,
- }
- ),
+ arguments: PathArguments::AngleBracketed(arguments),
})
)
|
@@ -770,15 +794,15 @@
bound_lifetimes: option!(syn!(BoundLifetimes)) >>
trait_ref: syn!(Path) >>
parenthesized: option!(cond_reduce!(
- trait_ref.segments.get(trait_ref.segments.len() - 1).item().parameters.is_empty(),
- syn!(ParenthesizedParameterData)
+ trait_ref.segments.get(trait_ref.segments.len() - 1).item().arguments.is_empty(),
+ syn!(ParenthesizedGenericArguments)
)) >>
({
let mut trait_ref = trait_ref;
if let Some(parenthesized) = parenthesized {
- let parenthesized = PathParameters::Parenthesized(parenthesized);
+ let parenthesized = PathArguments::Parenthesized(parenthesized);
let len = trait_ref.segments.len();
- trait_ref.segments.get_mut(len - 1).item_mut().parameters = parenthesized;
+ trait_ref.segments.get_mut(len - 1).item_mut().arguments = parenthesized;
}
PolyTraitRef {
bound_lifetimes: bound_lifetimes,
@@ -1000,45 +1024,43 @@
impl ToTokens for PathSegment {
fn to_tokens(&self, tokens: &mut Tokens) {
self.ident.to_tokens(tokens);
- self.parameters.to_tokens(tokens);
+ self.arguments.to_tokens(tokens);
}
}
- impl ToTokens for PathParameters {
+ impl ToTokens for PathArguments {
fn to_tokens(&self, tokens: &mut Tokens) {
match *self {
- PathParameters::None => {}
- PathParameters::AngleBracketed(ref parameters) => {
- parameters.to_tokens(tokens);
+ PathArguments::None => {}
+ PathArguments::AngleBracketed(ref arguments) => {
+ arguments.to_tokens(tokens);
}
- PathParameters::Parenthesized(ref parameters) => {
- parameters.to_tokens(tokens);
+ PathArguments::Parenthesized(ref arguments) => {
+ arguments.to_tokens(tokens);
}
}
}
}
- impl ToTokens for AngleBracketedParameterData {
+ impl ToTokens for GenericArgument {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ match *self {
+ GenericArgument::Lifetime(ref lt) => lt.to_tokens(tokens),
+ GenericArgument::Type(ref ty) => ty.to_tokens(tokens),
+ GenericArgument::TypeBinding(ref tb) => tb.to_tokens(tokens),
+ #[cfg(not(feature = "full"))]
+ GenericArgument::Const(_) => unreachable!(),
+ #[cfg(feature = "full")]
+ GenericArgument::Const(ref eb) => eb.to_tokens(tokens),
+ }
+ }
+ }
+
+ impl ToTokens for AngleBracketedGenericArguments {
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);
}
}
@@ -1051,7 +1073,7 @@
}
}
- impl ToTokens for ParenthesizedParameterData {
+ impl ToTokens for ParenthesizedGenericArguments {
fn to_tokens(&self, tokens: &mut Tokens) {
self.paren_token.surround(tokens, |tokens| {
self.inputs.to_tokens(tokens);
diff --git a/syn_codegen/src/main.rs b/syn_codegen/src/main.rs
index 4125774..2a60844 100644
--- a/syn_codegen/src/main.rs
+++ b/syn_codegen/src/main.rs
@@ -308,13 +308,16 @@
Fold,
}
- fn first_param(params: &PathParameters) -> &Type {
+ fn first_arg(params: &PathArguments) -> &Type {
let data = match *params {
- PathParameters::AngleBracketed(ref data) => data,
- _ => panic!("Expected at least 1 type parameter here"),
+ PathArguments::AngleBracketed(ref data) => data,
+ _ => panic!("Expected at least 1 type argument here"),
};
- data.types.first().expect("Expected at least 1 type parameter here").item()
+ match *data.args.first().expect("Expected at least 1 type argument here").item() {
+ &GenericArgument::Type(ref ty) => ty,
+ _ => panic!("Expected at least 1 type argument here"),
+ }
}
fn simple_visit(
@@ -360,7 +363,7 @@
}
if seg.ident == "Box" {
- let ty = first_param(&seg.parameters);
+ let ty = first_arg(&seg.arguments);
if let Some(seg) = last_segment(ty) {
if kind == Kind::Fold {
let name = quote!(*#name);
@@ -395,7 +398,7 @@
if seg.ident == "Vec" || seg.ident == "Delimited" {
let is_vec = seg.ident == "Vec";
- let ty = first_param(&seg.parameters);
+ let ty = first_arg(&seg.arguments);
if let Some(seg) = last_segment(ty) {
if let Some(val) = box_visit(seg, lookup, kind, "e!(it), eos_full) {
return Some(match kind {
@@ -462,7 +465,7 @@
}
if seg.ident == "Option" {
- let ty = first_param(&seg.parameters);
+ let ty = first_arg(&seg.arguments);
if let Some(seg) = last_segment(ty) {
let it = match kind {
Kind::Fold => quote!(it),
diff --git a/tests/test_derive_input.rs b/tests/test_derive_input.rs
index d4e0ada..a65472e 100644
--- a/tests/test_derive_input.rs
+++ b/tests/test_derive_input.rs
@@ -114,16 +114,16 @@
segments: vec![
PathSegment {
ident: "Vec".into(),
- parameters: PathParameters::AngleBracketed(
- AngleBracketedParameterData {
+ arguments: PathArguments::AngleBracketed(
+ AngleBracketedGenericArguments {
turbofish: None,
lt_token: Default::default(),
- lifetimes: Default::default(),
- types: vec![Type::from(TypePath {
- qself: None,
- path: "Attribute".into(),
- })].into(),
- bindings: Default::default(),
+ args: vec![
+ GenericArgument::Type(Type::from(TypePath {
+ qself: None,
+ path: "Attribute".into(),
+ })),
+ ].into(),
gt_token: Default::default(),
},
),