Add support for parsing const parameters
diff --git a/src/gen/fold.rs b/src/gen/fold.rs
index 186e380..ed7db7c 100644
--- a/src/gen/fold.rs
+++ b/src/gen/fold.rs
@@ -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" ) ]
@@ -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::*;
@@ -1491,6 +1505,11 @@
_visitor.fold_type_param(_binding_0),
)
}
+ Const(_binding_0, ) => {
+ Const (
+ _visitor.fold_const_param(_binding_0),
+ )
+ }
}
}
diff --git a/src/gen/visit.rs b/src/gen/visit.rs
index 3387d99..b91254f 100644
--- a/src/gen/visit.rs
+++ b/src/gen/visit.rs
@@ -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" ) ]
@@ -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::*;
@@ -1158,6 +1170,9 @@
Type(ref _binding_0, ) => {
_visitor.visit_type_param(&* _binding_0);
}
+ Const(ref _binding_0, ) => {
+ _visitor.visit_const_param(&* _binding_0);
+ }
}
}
diff --git a/src/gen/visit_mut.rs b/src/gen/visit_mut.rs
index aadef50..5ff8dce 100644
--- a/src/gen/visit_mut.rs
+++ b/src/gen/visit_mut.rs
@@ -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" ) ]
@@ -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::*;
@@ -1158,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);
+ }
}
}
diff --git a/src/generics.rs b/src/generics.rs
index f9fa655..d3c1ac0 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>,
+ }),
}
}
@@ -305,6 +315,26 @@
}
}
+ 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))) >>
+ (ConstParam {
+ attrs: attrs,
+ const_token: const_,
+ ident: ident,
+ colon_token: colon,
+ ty: ty,
+ eq_token: eq_def.as_ref().map(|&(eq, _)| eq),
+ default: eq_def.map(|(_, def)| def),
+ })
+ ));
+ }
+
impl Synom for WhereClause {
named!(parse -> Self, alt!(
do_parse!(
@@ -400,6 +430,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 +462,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 +538,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() {
+ self.eq_token.unwrap_or(Default::default()).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 707cbf6..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};