Rewrite tokenization with `proc-macro2` tokens
This ended up being a bit larger of a commit than I intended! I imagine that
this'll be one of the larger of the commits working towards #142. The purpose of
this commit is to use an updated version of the `quote` crate which doesn't work
with strings but rather works with tokens form the `proc-macro2` crate. The
`proc-macro2` crate itself is based on the proposed API for `proc_macro` itself,
and will continue to mirror it. The hope is that we'll flip an easy switch
eventually to use compiler tokens, whereas for now we'll stick to string parsing
at the lowest layer.
The largest change here is the addition of span information to the AST. Building
on the previous PRs to refactor the AST this makes it relatively easy from a
user perspective to digest and use the AST still, it's just a few extra fields
on the side. The fallout from this was then quite large throughout the
`printing` feature of the crate. The `parsing`, `fold`, and `visit` features
then followed suit to get updated as well.
This commit also changes the the semantics of the AST somewhat as well.
Previously it was inferred what tokens should be printed, for example if you
have a closure argument `syn` would automatically not print the colon in `a: b`
if the type listed was "infer this type". Now the colon is a separate field and
must be in sync with the type listed as the colon/type will be printed
unconditionally (emitting no output if both are `None`).
diff --git a/src/aster/generics.rs b/src/aster/generics.rs
index caee562..8cc84d0 100644
--- a/src/aster/generics.rs
+++ b/src/aster/generics.rs
@@ -5,6 +5,8 @@
use aster::ty_param::TyParamBuilder;
use aster::where_predicate::WherePredicateBuilder;
+use delimited::Delimited;
+
pub struct GenericsBuilder<F = Identity> {
callback: F,
lifetimes: Vec<LifetimeDef>,
@@ -37,16 +39,16 @@
pub fn from_generics_with_callback(generics: Generics, callback: F) -> Self {
GenericsBuilder {
callback: callback,
- lifetimes: generics.lifetimes,
- ty_params: generics.ty_params,
- predicates: generics.where_clause.predicates,
+ lifetimes: generics.lifetimes.into_vec(),
+ ty_params: generics.ty_params.into_vec(),
+ predicates: generics.where_clause.predicates.into_vec(),
}
}
pub fn with(self, generics: Generics) -> Self {
- self.with_lifetimes(generics.lifetimes.into_iter())
- .with_ty_params(generics.ty_params.into_iter())
- .with_predicates(generics.where_clause.predicates.into_iter())
+ self.with_lifetimes(generics.lifetimes.into_vec().into_iter())
+ .with_ty_params(generics.ty_params.into_vec().into_iter())
+ .with_predicates(generics.where_clause.predicates.into_vec().into_iter())
}
pub fn with_lifetimes<I, L>(mut self, iter: I) -> Self
@@ -141,7 +143,7 @@
let lifetime = lifetime.into_lifetime();
for lifetime_def in &mut self.lifetimes {
- lifetime_def.bounds.push(lifetime.clone());
+ lifetime_def.bounds.push_default(lifetime.clone());
}
for ty_param in &mut self.ty_params {
@@ -174,14 +176,14 @@
pub fn strip_lifetimes(mut self) -> Self {
for lifetime in &mut self.lifetimes {
- lifetime.bounds = vec![];
+ lifetime.bounds = Delimited::new();
}
self
}
pub fn strip_ty_params(mut self) -> Self {
for ty_param in &mut self.ty_params {
- ty_param.bounds = vec![];
+ ty_param.bounds = Delimited::new();
}
self
}
@@ -193,10 +195,15 @@
pub fn build(self) -> F::Result {
self.callback.invoke(Generics {
- lifetimes: self.lifetimes,
- ty_params: self.ty_params,
- where_clause: WhereClause { predicates: self.predicates },
- })
+ lifetimes: self.lifetimes.into(),
+ ty_params: self.ty_params.into(),
+ where_clause: WhereClause {
+ predicates: self.predicates.into(),
+ where_token: Default::default(),
+ },
+ lt_token: Default::default(),
+ gt_token: Default::default(),
+ })
}
}
diff --git a/src/aster/lifetime.rs b/src/aster/lifetime.rs
index 3bdf372..ead21fe 100644
--- a/src/aster/lifetime.rs
+++ b/src/aster/lifetime.rs
@@ -1,5 +1,6 @@
use {Ident, Lifetime, LifetimeDef};
use aster::invoke::{Invoke, Identity};
+use delimited::Delimited;
// ////////////////////////////////////////////////////////////////////////////
@@ -36,7 +37,8 @@
LifetimeDef {
attrs: vec![],
lifetime: self,
- bounds: vec![],
+ bounds: Delimited::new(),
+ colon_token: Default::default(),
}
}
}
@@ -95,9 +97,10 @@
pub fn build(self) -> F::Result {
self.callback.invoke(LifetimeDef {
- attrs: vec![],
- lifetime: self.lifetime,
- bounds: self.bounds,
- })
+ attrs: vec![],
+ lifetime: self.lifetime,
+ bounds: self.bounds.into(),
+ colon_token: Default::default(),
+ })
}
}
diff --git a/src/aster/path.rs b/src/aster/path.rs
index e53b142..23d644e 100644
--- a/src/aster/path.rs
+++ b/src/aster/path.rs
@@ -1,5 +1,5 @@
use {AngleBracketedParameterData, Generics, Ident, Lifetime, ParenthesizedParameterData, Path,
- PathParameters, PathSegment, Ty, TypeBinding};
+ PathParameters, PathSegment, Ty, TypeBinding, FunctionRetTy};
use aster::ident::ToIdent;
use aster::invoke::{Invoke, Identity};
use aster::lifetime::IntoLifetime;
@@ -139,9 +139,10 @@
pub fn build(self) -> F::Result {
self.callback.invoke(Path {
- global: self.global,
- segments: self.segments,
- })
+ global: self.global,
+ segments: self.segments.into(),
+ leading_colon: None,
+ })
}
}
@@ -181,10 +182,10 @@
pub fn with_generics(self, generics: Generics) -> Self {
// Strip off the bounds.
- let lifetimes = generics.lifetimes.iter().map(|lifetime_def| lifetime_def.lifetime.clone());
+ let lifetimes = generics.lifetimes.iter().map(|lifetime_def| lifetime_def.item().lifetime.clone());
let tys =
- generics.ty_params.iter().map(|ty_param| TyBuilder::new().id(ty_param.ident.clone()));
+ generics.ty_params.iter().map(|ty_param| TyBuilder::new().id(ty_param.item().ident.clone()));
self.with_lifetimes(lifetimes).with_tys(tys)
}
@@ -252,23 +253,29 @@
pub fn build_return(self, output: Option<Ty>) -> F::Result {
let data = ParenthesizedParameterData {
- inputs: self.tys,
- output: output,
+ inputs: self.tys.into(),
+ output: match output {
+ Some(ty) => FunctionRetTy::Ty(ty, Default::default()),
+ None => FunctionRetTy::Default,
+ },
+ paren_token: Default::default(),
};
let parameters = PathParameters::Parenthesized(data);
self.callback.invoke(PathSegment {
- ident: self.id,
- parameters: parameters,
- })
+ ident: self.id,
+ parameters: parameters,
+ })
}
pub fn build(self) -> F::Result {
let data = AngleBracketedParameterData {
- lifetimes: self.lifetimes,
- types: self.tys,
- bindings: self.bindings,
+ lifetimes: self.lifetimes.into(),
+ types: self.tys.into(),
+ bindings: self.bindings.into(),
+ gt_token: Default::default(),
+ lt_token: Default::default(),
};
let parameters = PathParameters::AngleBracketed(data);
@@ -306,9 +313,10 @@
let id = self.id;
self.builder.with_binding(TypeBinding {
- ident: id,
- ty: ty,
- })
+ ident: id,
+ ty: ty,
+ eq_token: Default::default(),
+ })
}
}
diff --git a/src/aster/qpath.rs b/src/aster/qpath.rs
index 71f68b1..ea36837 100644
--- a/src/aster/qpath.rs
+++ b/src/aster/qpath.rs
@@ -3,6 +3,7 @@
use aster::invoke::{Invoke, Identity};
use aster::path::{PathBuilder, PathSegmentBuilder};
use aster::ty::TyBuilder;
+use delimited::Delimited;
// ////////////////////////////////////////////////////////////////////////////
@@ -74,7 +75,8 @@
{
let path = Path {
global: false,
- segments: vec![],
+ segments: Delimited::new(),
+ leading_colon: None,
};
self.as_().build(path).id(id)
}
@@ -84,7 +86,8 @@
{
let path = Path {
global: false,
- segments: vec![],
+ segments: Delimited::new(),
+ leading_colon: None,
};
self.as_().build(path).segment(id)
}
@@ -101,6 +104,9 @@
qself: QSelf {
ty: Box::new(self.ty),
position: path.segments.len(),
+ as_token: Default::default(),
+ gt_token: Default::default(),
+ lt_token: Default::default(),
},
path: path,
}
@@ -137,7 +143,7 @@
type Result = F::Result;
fn invoke(mut self, segment: PathSegment) -> F::Result {
- self.path.segments.push(segment);
+ self.path.segments.push_default(segment);
self.builder.build(self.qself, self.path)
}
}
diff --git a/src/aster/ty.rs b/src/aster/ty.rs
index f43e4a5..1d8962c 100644
--- a/src/aster/ty.rs
+++ b/src/aster/ty.rs
@@ -116,7 +116,10 @@
}
pub fn build_slice(self, ty: Ty) -> F::Result {
- self.build(Ty::Slice(TySlice { ty: Box::new(ty) }))
+ self.build(Ty::Slice(TySlice {
+ ty: Box::new(ty),
+ bracket_token: Default::default(),
+ }))
}
pub fn slice(self) -> TyBuilder<TySliceBuilder<F>> {
@@ -132,11 +135,15 @@
}
pub fn never(self) -> F::Result {
- self.build(Ty::Never(TyNever {}))
+ self.build(Ty::Never(TyNever {
+ bang_token: Default::default(),
+ }))
}
pub fn infer(self) -> F::Result {
- self.build(Ty::Infer(TyInfer {}))
+ self.build(Ty::Infer(TyInfer {
+ underscore_token: Default::default()
+ }))
}
pub fn option(self) -> TyBuilder<TyOptionBuilder<F>> {
@@ -221,7 +228,7 @@
where F: Invoke<Ty>
{
pub fn mut_(mut self) -> Self {
- self.mutability = Mutability::Mutable;
+ self.mutability = Mutability::Mutable(Default::default());
self
}
@@ -240,6 +247,7 @@
self.builder.build(Ty::Rptr(TyRptr {
lifetime: self.lifetime,
ty: Box::new(ty),
+ and_token: Default::default(),
}))
}
@@ -414,7 +422,9 @@
}
pub fn with_generics(self, generics: Generics) -> Self {
- self.with_lifetimes(generics.lifetimes.into_iter().map(|def| def.lifetime))
+ self.with_lifetimes(generics.lifetimes.iter().map(|def| {
+ Lifetime { ident: def.item().lifetime.ident.clone() }
+ }))
}
pub fn with_lifetimes<I, L>(mut self, lifetimes: I) -> Self
@@ -437,7 +447,8 @@
pub fn build(self) -> F::Result {
let bounds = self.bounds;
self.builder.build(Ty::ImplTrait(TyImplTrait {
- bounds: bounds,
+ bounds: bounds.into(),
+ impl_token: Default::default(),
}))
}
}
@@ -479,7 +490,11 @@
}
pub fn build(self) -> F::Result {
- self.builder.build(Ty::Tup(TyTup { tys: self.tys }))
+ self.builder.build(Ty::Tup(TyTup {
+ tys: self.tys.into(),
+ paren_token: Default::default(),
+ lone_comma: None,
+ }))
}
}
diff --git a/src/aster/ty_param.rs b/src/aster/ty_param.rs
index d8d13d1..7f82f6b 100644
--- a/src/aster/ty_param.rs
+++ b/src/aster/ty_param.rs
@@ -1,4 +1,5 @@
use {Ident, LifetimeDef, Path, PolyTraitRef, TraitBoundModifier, Ty, TyParam, TyParamBound};
+use BoundLifetimes;
use aster::invoke::{Invoke, Identity};
use aster::lifetime::{IntoLifetime, IntoLifetimeDef, LifetimeDefBuilder};
use aster::path::{IntoPath, PathBuilder};
@@ -43,7 +44,7 @@
TyParamBuilder {
callback: callback,
id: ty_param.ident,
- bounds: ty_param.bounds,
+ bounds: ty_param.bounds.into_vec(),
default: ty_param.default,
}
}
@@ -87,11 +88,13 @@
pub fn build(self) -> F::Result {
self.callback.invoke(TyParam {
- attrs: vec![],
- ident: self.id,
- bounds: self.bounds,
- default: self.default,
- })
+ attrs: vec![],
+ ident: self.id,
+ bounds: self.bounds.into(),
+ default: self.default,
+ colon_token: Default::default(),
+ eq_token: Default::default(),
+ })
}
}
@@ -165,7 +168,7 @@
{
let builder = TraitTyParamBoundBuilder {
builder: self,
- modifier: TraitBoundModifier::Maybe,
+ modifier: TraitBoundModifier::Maybe(Default::default()),
};
PolyTraitRefBuilder::with_callback(path, builder)
@@ -245,9 +248,12 @@
pub fn build(self) -> F::Result {
self.callback.invoke(PolyTraitRef {
- bound_lifetimes: self.lifetimes,
- trait_ref: self.trait_ref,
- })
+ bound_lifetimes: Some(BoundLifetimes {
+ lifetimes: self.lifetimes.into(),
+ ..Default::default()
+ }),
+ trait_ref: self.trait_ref,
+ })
}
}
diff --git a/src/aster/where_predicate.rs b/src/aster/where_predicate.rs
index 611d058..16cdfd8 100644
--- a/src/aster/where_predicate.rs
+++ b/src/aster/where_predicate.rs
@@ -1,5 +1,5 @@
use {Ident, Lifetime, LifetimeDef, Ty, TyParamBound, WhereBoundPredicate, WherePredicate,
- WhereRegionPredicate};
+ WhereRegionPredicate, BoundLifetimes};
use aster::invoke::{Invoke, Identity};
use aster::lifetime::{IntoLifetime, IntoLifetimeDef, LifetimeDefBuilder};
use aster::path::IntoPath;
@@ -201,9 +201,13 @@
pub fn build(self) -> F::Result {
let predicate = WhereBoundPredicate {
- bound_lifetimes: self.bound_lifetimes,
+ bound_lifetimes: Some(BoundLifetimes {
+ lifetimes: self.bound_lifetimes.into(),
+ ..Default::default()
+ }),
bounded_ty: self.ty,
- bounds: self.bounds,
+ bounds: self.bounds.into(),
+ colon_token: Default::default(),
};
self.callback.invoke(WherePredicate::BoundPredicate(predicate))
@@ -251,7 +255,8 @@
pub fn build(self) -> F::Result {
let predicate = WhereRegionPredicate {
lifetime: self.lifetime,
- bounds: self.bounds,
+ bounds: self.bounds.into(),
+ colon_token: Default::default(),
};
self.callback.invoke(WherePredicate::RegionPredicate(predicate))
diff --git a/src/attr.rs b/src/attr.rs
index f839ec4..df51583 100644
--- a/src/attr.rs
+++ b/src/attr.rs
@@ -1,11 +1,16 @@
use super::*;
+use delimited::Delimited;
use std::iter;
+use proc_macro2::{self, Delimiter, TokenKind, OpKind};
+
ast_struct! {
/// Doc-comments are promoted to attributes that have `is_sugared_doc` = true
pub struct Attribute {
pub style: AttrStyle,
+ pub pound_token: tokens::Pound,
+ pub bracket_token: tokens::Bracket,
/// The path of the attribute.
///
@@ -27,7 +32,7 @@
/// Parses the tokens after the path as a [`MetaItem`](enum.MetaItem.html) if possible.
pub fn meta_item(&self) -> Option<MetaItem> {
let name = if self.path.segments.len() == 1 {
- &self.path.segments[0].ident
+ &self.path.segments.get(0).item().ident
} else {
return None;
};
@@ -37,76 +42,11 @@
}
if self.tts.len() == 1 {
- if let TokenTree::Delimited(Delimited { delim: DelimToken::Paren, ref tts }) = self.tts[0] {
- fn nested_meta_item_from_tokens(tts: &[TokenTree]) -> Option<(NestedMetaItem, &[TokenTree])> {
- assert!(!tts.is_empty());
-
- match tts[0] {
- TokenTree::Token(Token::Literal(ref lit)) => {
- Some((NestedMetaItem::Literal(lit.clone()), &tts[1..]))
- }
-
- TokenTree::Token(Token::Ident(ref ident)) => {
- if tts.len() >= 3 {
- if let TokenTree::Token(Token::Eq) = tts[1] {
- if let TokenTree::Token(Token::Literal(ref lit)) = tts[2] {
- let pair = MetaNameValue {
- ident: ident.clone(),
- lit: lit.clone(),
- };
- return Some((NestedMetaItem::MetaItem(MetaItem::NameValue(pair)), &tts[3..]));
- }
- }
- }
-
- if tts.len() >= 2 {
- if let TokenTree::Delimited(Delimited { delim: DelimToken::Paren, tts: ref inner_tts }) = tts[1] {
- return match list_of_nested_meta_items_from_tokens(vec![], inner_tts) {
- Some(nested_meta_items) => {
- let list = MetaItemList {
- ident: ident.clone(),
- nested: nested_meta_items,
- };
- Some((NestedMetaItem::MetaItem(MetaItem::List(list)), &tts[2..]))
- }
-
- None => None
- };
- }
- }
-
- Some((NestedMetaItem::MetaItem(MetaItem::Word(ident.clone())), &tts[1..]))
- }
-
- _ => None
- }
- }
-
- fn list_of_nested_meta_items_from_tokens(mut result: Vec<NestedMetaItem>, tts: &[TokenTree]) -> Option<Vec<NestedMetaItem>> {
- if tts.is_empty() {
- return Some(result);
- }
-
- match nested_meta_item_from_tokens(tts) {
- Some((nested_meta_item, rest)) => {
- result.push(nested_meta_item);
- if rest.is_empty() {
- list_of_nested_meta_items_from_tokens(result, rest)
- }
- else if let TokenTree::Token(Token::Comma) = rest[0] {
- list_of_nested_meta_items_from_tokens(result, &rest[1..])
- }
- else {
- None
- }
- }
-
- None => None
- }
- }
-
- if let Some(nested_meta_items) = list_of_nested_meta_items_from_tokens(vec![], tts) {
+ if let TokenKind::Sequence(Delimiter::Parenthesis, ref ts) = self.tts[0].0.kind {
+ let tokens = ts.clone().into_iter().collect::<Vec<_>>();
+ if let Some(nested_meta_items) = list_of_nested_meta_items_from_tokens(&tokens) {
return Some(MetaItem::List(MetaItemList {
+ paren_token: tokens::Paren(Span(self.tts[0].0.span)),
ident: name.clone(),
nested: nested_meta_items,
}));
@@ -115,11 +55,15 @@
}
if self.tts.len() == 2 {
- if let TokenTree::Token(Token::Eq) = self.tts[0] {
- if let TokenTree::Token(Token::Literal(ref lit)) = self.tts[1] {
+ if let TokenKind::Op('=', OpKind::Alone) = self.tts[0].0.kind {
+ if let TokenKind::Literal(ref lit) = self.tts[1].0.kind {
return Some(MetaItem::NameValue(MetaNameValue {
ident: name.clone(),
- lit: lit.clone(),
+ eq_token: tokens::Eq([Span(self.tts[0].0.span)]),
+ lit: Lit {
+ value: LitKind::Other(lit.clone()),
+ span: Span(self.tts[1].0.span),
+ },
}));
}
}
@@ -129,17 +73,109 @@
}
}
+fn nested_meta_item_from_tokens(tts: &[proc_macro2::TokenTree])
+ -> Option<(NestedMetaItem, &[proc_macro2::TokenTree])>
+{
+ assert!(!tts.is_empty());
+
+ match tts[0].kind {
+ TokenKind::Literal(ref lit) => {
+ let lit = Lit {
+ value: LitKind::Other(lit.clone()),
+ span: Span(tts[0].span),
+ };
+ Some((NestedMetaItem::Literal(lit), &tts[1..]))
+ }
+
+ TokenKind::Word(sym) => {
+ let ident = Ident::new(sym, Span(tts[0].span));
+ if tts.len() >= 3 {
+ if let TokenKind::Op('=', OpKind::Alone) = tts[1].kind {
+ if let TokenKind::Literal(ref lit) = tts[2].kind {
+ let pair = MetaNameValue {
+ ident: Ident::new(sym, Span(tts[0].span)),
+ eq_token: tokens::Eq([Span(tts[1].span)]),
+ lit: Lit {
+ value: LitKind::Other(lit.clone()),
+ span: Span(tts[2].span),
+ },
+ };
+ return Some((MetaItem::NameValue(pair).into(), &tts[3..]));
+ }
+ }
+ }
+
+ if tts.len() >= 2 {
+ if let TokenKind::Sequence(Delimiter::Parenthesis, ref inner_tts) = tts[1].kind {
+ let inner_tts = inner_tts.clone().into_iter().collect::<Vec<_>>();
+ return match list_of_nested_meta_items_from_tokens(&inner_tts) {
+ Some(nested_meta_items) => {
+ let list = MetaItemList {
+ ident: ident,
+ paren_token: tokens::Paren(Span(tts[1].span)),
+ nested: nested_meta_items,
+ };
+ Some((MetaItem::List(list).into(), &tts[2..]))
+ }
+
+ None => None
+ };
+ }
+ }
+
+ Some((MetaItem::Word(ident).into(), &tts[1..]))
+ }
+
+ _ => None
+ }
+}
+
+fn list_of_nested_meta_items_from_tokens(mut tts: &[proc_macro2::TokenTree])
+ -> Option<Delimited<NestedMetaItem, tokens::Comma>>
+{
+ let mut delimited = Delimited::new();
+ let mut first = true;
+
+ while !tts.is_empty() {
+ let prev_comma = if first {
+ first = false;
+ None
+ } else if let TokenKind::Op(',', OpKind::Alone) = tts[0].kind {
+ let tok = tokens::Comma([Span(tts[0].span)]);
+ tts = &tts[1..];
+ if tts.is_empty() {
+ break
+ }
+ Some(tok)
+ } else {
+ return None
+ };
+ let (nested, rest) = match nested_meta_item_from_tokens(tts) {
+ Some(pair) => pair,
+ None => return None,
+ };
+ match prev_comma {
+ Some(comma) => delimited.push_next(nested, comma),
+ None => delimited.push_first(nested),
+ }
+ tts = rest;
+ }
+
+ Some(delimited)
+}
+
+
ast_enum! {
/// Distinguishes between Attributes that decorate items and Attributes that
/// are contained as statements within items. These two cases need to be
/// distinguished for pretty-printing.
#[cfg_attr(feature = "clone-impls", derive(Copy))]
pub enum AttrStyle {
- /// Attribute of the form `#![...]`.
+ /// Attribute of the form `#[...]`.
Outer,
- /// Attribute of the form `#[...]`.
- Inner,
+ /// Attribute of the form `#![...]`.
+ Inner(tokens::Bang),
}
}
@@ -162,10 +198,12 @@
/// E.g. `derive` in `#[derive(..)]`
pub ident: Ident,
+ pub paren_token: tokens::Paren,
+
/// Arguments to this attribute
///
/// E.g. `..` in `#[derive(..)]`
- pub nested: Vec<NestedMetaItem>,
+ pub nested: Delimited<NestedMetaItem, tokens::Comma>,
}),
/// Name-value meta item.
@@ -177,6 +215,8 @@
/// E.g. `feature` in `#[feature = "foo"]`
pub ident: Ident,
+ pub eq_token: tokens::Eq,
+
/// Arguments to this attribute
///
/// E.g. `"foo"` in `#[feature = "foo"]`
@@ -241,7 +281,7 @@
fn inner(self) -> Self::Ret {
fn is_inner(attr: &&Attribute) -> bool {
match attr.style {
- AttrStyle::Inner => true,
+ AttrStyle::Inner(_) => true,
_ => false,
}
}
@@ -252,11 +292,25 @@
#[cfg(feature = "parsing")]
pub mod parsing {
use super::*;
- use lit::{Lit, StrStyle};
- use mac::{Token, TokenTree};
+ use mac::TokenTree;
use mac::parsing::token_trees;
use synom::space::{block_comment, whitespace};
use ty::parsing::mod_style_path;
+ use proc_macro2::{self, TokenKind, OpKind, Literal};
+
+ fn eq() -> TokenTree {
+ TokenTree(proc_macro2::TokenTree {
+ span: Default::default(),
+ kind: TokenKind::Op('=', OpKind::Alone),
+ })
+ }
+
+ fn doc(s: &str) -> TokenTree {
+ TokenTree(proc_macro2::TokenTree {
+ span: Default::default(),
+ kind: TokenKind::Literal(Literal::doccomment(s)),
+ })
+ }
#[cfg(feature = "full")]
named!(pub inner_attr -> Attribute, alt!(
@@ -272,10 +326,12 @@
let (path, tts) = path_and_tts;
Attribute {
- style: AttrStyle::Inner,
+ style: AttrStyle::Inner(tokens::Bang::default()),
path: path,
tts: tts,
is_sugared_doc: false,
+ pound_token: tokens::Pound::default(),
+ bracket_token: tokens::Bracket::default(),
}
})
)
@@ -284,13 +340,15 @@
punct!("//!") >>
content: take_until!("\n") >>
(Attribute {
- style: AttrStyle::Inner,
+ style: AttrStyle::Inner(tokens::Bang::default()),
path: "doc".into(),
tts: vec![
- TokenTree::Token(Token::Eq),
- TokenTree::Token(Token::Literal(Lit::Str(format!("//!{}", content).into(), StrStyle::Cooked))),
+ eq(),
+ doc(&format!("//!{}", content)),
],
is_sugared_doc: true,
+ pound_token: tokens::Pound::default(),
+ bracket_token: tokens::Bracket::default(),
})
)
|
@@ -299,13 +357,15 @@
peek!(tag!("/*!")) >>
com: block_comment >>
(Attribute {
- style: AttrStyle::Inner,
+ style: AttrStyle::Inner(tokens::Bang::default()),
path: "doc".into(),
tts: vec![
- TokenTree::Token(Token::Eq),
- TokenTree::Token(Token::Literal(Lit::Str(com.into(), StrStyle::Cooked))),
+ eq(),
+ doc(com),
],
is_sugared_doc: true,
+ pound_token: tokens::Pound::default(),
+ bracket_token: tokens::Bracket::default(),
})
)
));
@@ -326,6 +386,8 @@
path: path,
tts: tts,
is_sugared_doc: false,
+ pound_token: tokens::Pound::default(),
+ bracket_token: tokens::Bracket::default(),
}
})
)
@@ -338,10 +400,12 @@
style: AttrStyle::Outer,
path: "doc".into(),
tts: vec![
- TokenTree::Token(Token::Eq),
- TokenTree::Token(Token::Literal(Lit::Str(format!("///{}", content).into(), StrStyle::Cooked))),
+ eq(),
+ doc(&format!("///{}", content)),
],
is_sugared_doc: true,
+ pound_token: tokens::Pound::default(),
+ bracket_token: tokens::Bracket::default(),
})
)
|
@@ -353,10 +417,12 @@
style: AttrStyle::Outer,
path: "doc".into(),
tts: vec![
- TokenTree::Token(Token::Eq),
- TokenTree::Token(Token::Literal(Lit::Str(com.into(), StrStyle::Cooked))),
+ eq(),
+ doc(com),
],
is_sugared_doc: true,
+ pound_token: tokens::Pound::default(),
+ bracket_token: tokens::Bracket::default(),
})
)
));
@@ -365,77 +431,71 @@
#[cfg(feature = "printing")]
mod printing {
use super::*;
- use lit::{Lit, StrStyle};
- use mac::{Token, TokenTree};
use quote::{Tokens, ToTokens};
- use ty::Path;
+ use proc_macro2::{Literal, TokenTree};
impl ToTokens for Attribute {
fn to_tokens(&self, tokens: &mut Tokens) {
// If this was a sugared doc, emit it in its original form instead of `#[doc = "..."]`
- match *self {
- Attribute {
- ref style,
- path: Path { global: false, ref segments },
- ref tts,
- is_sugared_doc: true,
- } if segments.len() == 1 &&
- segments[0].ident == "doc" &&
- segments[0].parameters.is_empty() &&
- tts.len() == 2 =>
- {
- if let TokenTree::Token(Token::Eq) = self.tts[0] {
- if let TokenTree::Token(Token::Literal(Lit::Str(ref value, StrStyle::Cooked))) = self.tts[1] {
- match *style {
- AttrStyle::Inner if value.starts_with("//!") => {
- tokens.append(&format!("{}\n", value));
- return;
- }
- AttrStyle::Inner if value.starts_with("/*!") => {
- tokens.append(value);
- return;
- }
- AttrStyle::Outer if value.starts_with("///") => {
- tokens.append(&format!("{}\n", value));
- return;
- }
- AttrStyle::Outer if value.starts_with("/**") => {
- tokens.append(value);
- return;
- }
- _ => {}
+ if self.is_sugared_doc {
+ if let Some(MetaItem::NameValue(ref pair)) = self.meta_item() {
+ if pair.ident == "doc" {
+ let value = pair.lit.value.to_string();
+ match self.style {
+ AttrStyle::Inner(_) if value.starts_with("//!") => {
+ let doc = Literal::doccomment(&format!("{}\n", value));
+ tokens.append(TokenTree {
+ span: pair.lit.span.0,
+ kind: TokenKind::Literal(doc),
+ });
+ return;
}
+ AttrStyle::Inner(_) if value.starts_with("/*!") => {
+ pair.lit.to_tokens(tokens);
+ return;
+ }
+ AttrStyle::Outer if value.starts_with("///") => {
+ let doc = Literal::doccomment(&format!("{}\n", value));
+ tokens.append(TokenTree {
+ span: pair.lit.span.0,
+ kind: TokenKind::Literal(doc),
+ });
+ return;
+ }
+ AttrStyle::Outer if value.starts_with("/**") => {
+ pair.lit.to_tokens(tokens);
+ return;
+ }
+ _ => {}
}
}
}
-
- _ => {}
}
- tokens.append("#");
- if let AttrStyle::Inner = self.style {
- tokens.append("!");
+ self.pound_token.to_tokens(tokens);
+ if let AttrStyle::Inner(ref b) = self.style {
+ b.to_tokens(tokens);
}
- tokens.append("[");
- self.path.to_tokens(tokens);
- tokens.append_all(&self.tts);
- tokens.append("]");
+ self.bracket_token.surround(tokens, |tokens| {
+ self.path.to_tokens(tokens);
+ tokens.append_all(&self.tts);
+ });
}
}
impl ToTokens for MetaItemList {
fn to_tokens(&self, tokens: &mut Tokens) {
self.ident.to_tokens(tokens);
- tokens.append("(");
- tokens.append_separated(&self.nested, ",");
- tokens.append(")");
+ self.paren_token.surround(tokens, |tokens| {
+ self.nested.to_tokens(tokens);
+ })
}
}
impl ToTokens for MetaNameValue {
fn to_tokens(&self, tokens: &mut Tokens) {
self.ident.to_tokens(tokens);
- tokens.append("=");
+ self.eq_token.to_tokens(tokens);
self.lit.to_tokens(tokens);
}
}
diff --git a/src/constant.rs b/src/constant.rs
index 2267b50..1a2818c 100644
--- a/src/constant.rs
+++ b/src/constant.rs
@@ -1,4 +1,5 @@
use super::*;
+use delimited::Delimited;
ast_enum_of_structs! {
pub enum ConstExpr {
@@ -8,7 +9,9 @@
pub func: Box<ConstExpr>,
/// The arguments to the function being called
- pub args: Vec<ConstExpr>,
+ pub args: Delimited<ConstExpr, tokens::Comma>,
+
+ pub paren_token: tokens::Paren,
}),
/// A binary operation (For example: `a + b`, `a * b`)
@@ -42,6 +45,8 @@
/// Type casted to
pub ty: Box<Ty>,
+
+ pub as_token: tokens::As,
}),
/// Variable reference, possibly containing `::` and/or type
@@ -55,12 +60,15 @@
/// Index expression
pub index: Box<ConstExpr>,
+
+ pub bracket_token: tokens::Bracket,
}),
/// No-op: used solely so we can pretty-print faithfully
pub Paren(ConstParen {
/// Expression that's parenthesized
pub expr: Box<ConstExpr>,
+ pub paren_token: tokens::Paren,
}),
/// If compiling with full support for expression syntax, any expression is
@@ -103,7 +111,12 @@
) >>
many0!(alt!(
tap!(args: and_call => {
- e = ConstCall { func: Box::new(e), args: args }.into();
+ let (args, paren) = args;
+ e = ConstCall {
+ func: Box::new(e),
+ args: args,
+ paren_token: paren,
+ }.into();
})
|
tap!(more: and_binary => {
@@ -112,21 +125,32 @@
})
|
tap!(ty: and_cast => {
- e = ConstCast { expr: Box::new(e), ty: Box::new(ty) }.into();
+ let (ty, token) = ty;
+ e = ConstCast {
+ expr: Box::new(e),
+ ty: Box::new(ty),
+ as_token: token,
+ }.into();
})
|
tap!(i: and_index => {
- e = ConstIndex { expr: Box::new(e), index: Box::new(i) }.into();
+ let (i, bracket) = i;
+ e = ConstIndex {
+ expr: Box::new(e),
+ index: Box::new(i),
+ bracket_token: bracket,
+ }.into();
})
)) >>
(e)
));
- named!(and_call -> Vec<ConstExpr>, do_parse!(
+ named!(and_call -> (Delimited<ConstExpr, tokens::Comma>, tokens::Paren), do_parse!(
punct!("(") >>
- args: terminated_list!(punct!(","), const_expr) >>
+ args: terminated_list!(map!(punct!(","), |_| tokens::Comma::default()),
+ const_expr) >>
punct!(")") >>
- (args)
+ (args, tokens::Paren::default())
));
named!(and_binary -> (BinOp, ConstExpr), tuple!(binop, const_expr));
@@ -141,19 +165,27 @@
named!(expr_path -> ConstExpr, map!(path, ConstExpr::Path));
- named!(and_index -> ConstExpr, delimited!(punct!("["), const_expr, punct!("]")));
+ named!(and_index -> (ConstExpr, tokens::Bracket), do_parse!(
+ punct!("[") >>
+ expr: const_expr >>
+ punct!("]") >>
+ (expr, tokens::Bracket::default())
+ ));
named!(expr_paren -> ConstExpr, do_parse!(
punct!("(") >>
e: const_expr >>
punct!(")") >>
- (ConstParen { expr: Box::new(e) }.into())
+ (ConstParen {
+ expr: Box::new(e),
+ paren_token: tokens::Paren::default(),
+ }.into())
));
- named!(and_cast -> Ty, do_parse!(
+ named!(and_cast -> (Ty, tokens::As), do_parse!(
keyword!("as") >>
ty: ty >>
- (ty)
+ (ty, tokens::As::default())
));
}
@@ -165,9 +197,9 @@
impl ToTokens for ConstCall {
fn to_tokens(&self, tokens: &mut Tokens) {
self.func.to_tokens(tokens);
- tokens.append("(");
- tokens.append_separated(&self.args, ",");
- tokens.append(")");
+ self.paren_token.surround(tokens, |tokens| {
+ self.args.to_tokens(tokens);
+ })
}
}
@@ -189,7 +221,7 @@
impl ToTokens for ConstCast {
fn to_tokens(&self, tokens: &mut Tokens) {
self.expr.to_tokens(tokens);
- tokens.append("as");
+ self.as_token.to_tokens(tokens);
self.ty.to_tokens(tokens);
}
}
@@ -197,17 +229,17 @@
impl ToTokens for ConstIndex {
fn to_tokens(&self, tokens: &mut Tokens) {
self.expr.to_tokens(tokens);
- tokens.append("[");
- self.index.to_tokens(tokens);
- tokens.append("]");
+ self.bracket_token.surround(tokens, |tokens| {
+ self.index.to_tokens(tokens);
+ })
}
}
impl ToTokens for ConstParen {
fn to_tokens(&self, tokens: &mut Tokens) {
- tokens.append("(");
- self.expr.to_tokens(tokens);
- tokens.append(")");
+ self.paren_token.surround(tokens, |tokens| {
+ self.expr.to_tokens(tokens);
+ })
}
}
diff --git a/src/data.rs b/src/data.rs
index 3916b25..5085986 100644
--- a/src/data.rs
+++ b/src/data.rs
@@ -1,4 +1,5 @@
use super::*;
+use delimited::Delimited;
ast_struct! {
/// An enum variant.
@@ -14,6 +15,8 @@
/// Explicit discriminant, e.g. `Foo = 1`
pub discriminant: Option<ConstExpr>,
+
+ pub eq_token: Option<tokens::Eq>,
}
}
@@ -21,10 +24,10 @@
/// Data stored within an enum variant or struct.
pub enum VariantData {
/// Struct variant, e.g. `Point { x: f64, y: f64 }`.
- Struct(Vec<Field>),
+ Struct(Delimited<Field, tokens::Comma>, tokens::Brace),
/// Tuple variant, e.g. `Some(T)`.
- Tuple(Vec<Field>),
+ Tuple(Delimited<Field, tokens::Comma>, tokens::Paren),
/// Unit variant, e.g. `None`.
Unit,
@@ -32,23 +35,24 @@
}
impl VariantData {
- /// Slice containing the fields stored in the variant.
- pub fn fields(&self) -> &[Field] {
- match *self {
- VariantData::Struct(ref fields) |
- VariantData::Tuple(ref fields) => fields,
- VariantData::Unit => &[],
- }
- }
-
- /// Mutable slice containing the fields stored in the variant.
- pub fn fields_mut(&mut self) -> &mut [Field] {
- match *self {
- VariantData::Struct(ref mut fields) |
- VariantData::Tuple(ref mut fields) => fields,
- VariantData::Unit => &mut [],
- }
- }
+ // TODO: expose this?
+ // /// Slice containing the fields stored in the variant.
+ // pub fn fields(&self) -> &Delimited<Field, tokens::Comma> {
+ // match *self {
+ // VariantData::Struct(ref fields, _) |
+ // VariantData::Tuple(ref fields, _) => fields,
+ // VariantData::Unit => &[],
+ // }
+ // }
+ //
+ // /// Mutable slice containing the fields stored in the variant.
+ // pub fn fields_mut(&mut self) -> &mut Delimited<Field, tokens::Comma> {
+ // match *self {
+ // VariantData::Struct(ref mut fields, _) |
+ // VariantData::Tuple(ref mut fields, _) => fields,
+ // VariantData::Unit => &mut [],
+ // }
+ // }
}
ast_struct! {
@@ -67,23 +71,36 @@
/// Type of the field.
pub ty: Ty,
+
+ pub colon_token: Option<tokens::Colon>,
}
}
-ast_enum! {
+ast_enum_of_structs! {
/// Visibility level of an item.
pub enum Visibility {
/// Public, i.e. `pub`.
- Public,
+ pub Public(VisPublic {
+ pub pub_token: tokens::Pub,
+ }),
/// Crate-visible, i.e. `pub(crate)`.
- Crate,
+ pub Crate(VisCrate {
+ pub pub_token: tokens::Pub,
+ pub paren_token: tokens::Paren,
+ pub crate_token: tokens::Crate,
+ }),
/// Restricted, e.g. `pub(self)` or `pub(super)` or `pub(in some::module)`.
- Restricted(Box<Path>),
+ pub Restricted(VisRestricted {
+ pub pub_token: tokens::Pub,
+ pub paren_token: tokens::Paren,
+ pub in_token: Option<tokens::In>,
+ pub path: Box<Path>,
+ }),
/// Inherited, i.e. private.
- Inherited,
+ pub Inherited(VisInherited {}),
}
}
@@ -102,42 +119,43 @@
use ident::parsing::ident;
use ty::parsing::{mod_style_path, ty};
- named!(pub struct_body -> (WhereClause, VariantData), alt!(
+ named!(pub struct_body -> (WhereClause, VariantData, Option<tokens::Semi>), alt!(
do_parse!(
wh: where_clause >>
body: struct_like_body >>
- (wh, VariantData::Struct(body))
+ (wh, VariantData::Struct(body.0, body.1), None)
)
|
do_parse!(
body: tuple_like_body >>
wh: where_clause >>
punct!(";") >>
- (wh, VariantData::Tuple(body))
+ (wh, VariantData::Tuple(body.0, body.1), Some(tokens::Semi::default()))
)
|
do_parse!(
wh: where_clause >>
punct!(";") >>
- (wh, VariantData::Unit)
+ (wh, VariantData::Unit, Some(tokens::Semi::default()))
)
));
- named!(pub enum_body -> (WhereClause, Vec<Variant>), do_parse!(
+ named!(pub enum_body -> (WhereClause, Delimited<Variant, tokens::Comma>, tokens::Brace), do_parse!(
wh: where_clause >>
punct!("{") >>
- variants: terminated_list!(punct!(","), variant) >>
+ variants: terminated_list!(map!(punct!(","), |_| tokens::Comma::default()),
+ variant) >>
punct!("}") >>
- (wh, variants)
+ (wh, variants, tokens::Brace::default())
));
named!(variant -> Variant, do_parse!(
attrs: many0!(outer_attr) >>
id: ident >>
data: alt!(
- struct_like_body => { VariantData::Struct }
+ struct_like_body => { |(d, b)| VariantData::Struct(d, b) }
|
- tuple_like_body => { VariantData::Tuple }
+ tuple_like_body => { |(d, b)| VariantData::Tuple(d, b) }
|
epsilon!() => { |_| VariantData::Unit }
) >>
@@ -146,6 +164,7 @@
ident: id,
attrs: attrs,
data: data,
+ eq_token: disr.as_ref().map(|_| tokens::Eq::default()),
discriminant: disr,
})
));
@@ -163,18 +182,20 @@
#[cfg(feature = "full")]
named!(after_discriminant -> &str, peek!(alt!(punct!(",") | punct!("}"))));
- named!(pub struct_like_body -> Vec<Field>, do_parse!(
+ named!(pub struct_like_body -> (Delimited<Field, tokens::Comma>, tokens::Brace), do_parse!(
punct!("{") >>
- fields: terminated_list!(punct!(","), struct_field) >>
+ fields: terminated_list!(map!(punct!(","), |_| tokens::Comma::default()),
+ struct_field) >>
punct!("}") >>
- (fields)
+ (fields, tokens::Brace::default())
));
- named!(tuple_like_body -> Vec<Field>, do_parse!(
+ named!(tuple_like_body -> (Delimited<Field, tokens::Comma>, tokens::Paren), do_parse!(
punct!("(") >>
- fields: terminated_list!(punct!(","), tuple_field) >>
+ fields: terminated_list!(map!(punct!(","), |_| tokens::Comma::default()),
+ tuple_field) >>
punct!(")") >>
- (fields)
+ (fields, tokens::Paren::default())
));
named!(struct_field -> Field, do_parse!(
@@ -188,6 +209,7 @@
vis: vis,
attrs: attrs,
ty: ty,
+ colon_token: Some(tokens::Colon::default()),
})
));
@@ -197,6 +219,7 @@
ty: ty >>
(Field {
ident: None,
+ colon_token: None,
vis: vis,
attrs: attrs,
ty: ty,
@@ -209,7 +232,11 @@
punct!("(") >>
keyword!("crate") >>
punct!(")") >>
- (Visibility::Crate)
+ (Visibility::Crate(VisCrate {
+ crate_token: tokens::Crate::default(),
+ paren_token: tokens::Paren::default(),
+ pub_token: tokens::Pub::default(),
+ }))
)
|
do_parse!(
@@ -217,7 +244,12 @@
punct!("(") >>
keyword!("self") >>
punct!(")") >>
- (Visibility::Restricted(Box::new("self".into())))
+ (Visibility::Restricted(VisRestricted {
+ path: Box::new("self".into()),
+ in_token: None,
+ paren_token: tokens::Paren::default(),
+ pub_token: tokens::Pub::default(),
+ }))
)
|
do_parse!(
@@ -225,7 +257,12 @@
punct!("(") >>
keyword!("super") >>
punct!(")") >>
- (Visibility::Restricted(Box::new("super".into())))
+ (Visibility::Restricted(VisRestricted {
+ path: Box::new("super".into()),
+ in_token: None,
+ paren_token: tokens::Paren::default(),
+ pub_token: tokens::Pub::default(),
+ }))
)
|
do_parse!(
@@ -234,12 +271,21 @@
keyword!("in") >>
restricted: mod_style_path >>
punct!(")") >>
- (Visibility::Restricted(Box::new(restricted)))
+ (Visibility::Restricted(VisRestricted {
+ path: Box::new(restricted),
+ in_token: Some(tokens::In::default()),
+ paren_token: tokens::Paren::default(),
+ pub_token: tokens::Pub::default(),
+ }))
)
|
- keyword!("pub") => { |_| Visibility::Public }
+ keyword!("pub") => { |_| {
+ Visibility::Public(VisPublic {
+ pub_token: tokens::Pub::default(),
+ })
+ } }
|
- epsilon!() => { |_| Visibility::Inherited }
+ epsilon!() => { |_| Visibility::Inherited(VisInherited {}) }
));
}
@@ -250,30 +296,26 @@
impl ToTokens for Variant {
fn to_tokens(&self, tokens: &mut Tokens) {
- for attr in &self.attrs {
- attr.to_tokens(tokens);
- }
+ tokens.append_all(&self.attrs);
self.ident.to_tokens(tokens);
self.data.to_tokens(tokens);
- if let Some(ref disr) = self.discriminant {
- tokens.append("=");
- disr.to_tokens(tokens);
- }
+ self.eq_token.to_tokens(tokens);
+ self.discriminant.to_tokens(tokens);
}
}
impl ToTokens for VariantData {
fn to_tokens(&self, tokens: &mut Tokens) {
match *self {
- VariantData::Struct(ref fields) => {
- tokens.append("{");
- tokens.append_separated(fields, ",");
- tokens.append("}");
+ VariantData::Struct(ref fields, ref brace) => {
+ brace.surround(tokens, |tokens| {
+ fields.to_tokens(tokens);
+ });
}
- VariantData::Tuple(ref fields) => {
- tokens.append("(");
- tokens.append_separated(fields, ",");
- tokens.append(")");
+ VariantData::Tuple(ref fields, ref paren) => {
+ paren.surround(tokens, |tokens| {
+ fields.to_tokens(tokens);
+ });
}
VariantData::Unit => {}
}
@@ -282,47 +324,41 @@
impl ToTokens for Field {
fn to_tokens(&self, tokens: &mut Tokens) {
- for attr in &self.attrs {
- attr.to_tokens(tokens);
- }
+ tokens.append_all(&self.attrs);
self.vis.to_tokens(tokens);
- if let Some(ref ident) = self.ident {
- ident.to_tokens(tokens);
- tokens.append(":");
- }
+ self.ident.to_tokens(tokens);
+ self.colon_token.to_tokens(tokens);
self.ty.to_tokens(tokens);
}
}
- impl ToTokens for Visibility {
+ impl ToTokens for VisPublic {
fn to_tokens(&self, tokens: &mut Tokens) {
- match *self {
- Visibility::Public => tokens.append("pub"),
- Visibility::Crate => {
- tokens.append("pub");
- tokens.append("(");
- tokens.append("crate");
- tokens.append(")");
- }
- Visibility::Restricted(ref path) => {
- tokens.append("pub");
- tokens.append("(");
+ self.pub_token.to_tokens(tokens)
+ }
+ }
- if !path.global &&
- path.segments.len() == 1 &&
- (path.segments[0].ident == "self" || path.segments[0].ident == "super") &&
- path.segments[0].parameters.is_empty() {
+ impl ToTokens for VisCrate {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ self.pub_token.to_tokens(tokens);
+ self.paren_token.surround(tokens, |tokens| {
+ self.crate_token.to_tokens(tokens);
+ })
+ }
+ }
- // Don't emit preceding `in` if path is `self` or `super`
- } else {
- tokens.append("in");
- }
+ impl ToTokens for VisRestricted {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ self.pub_token.to_tokens(tokens);
+ self.paren_token.surround(tokens, |tokens| {
+ self.in_token.to_tokens(tokens);
+ self.path.to_tokens(tokens);
+ });
+ }
+ }
- path.to_tokens(tokens);
- tokens.append(")");
- }
- Visibility::Inherited => {}
- }
+ impl ToTokens for VisInherited {
+ fn to_tokens(&self, _tokens: &mut Tokens) {
}
}
}
diff --git a/src/derive.rs b/src/derive.rs
index 3b22b0f..cf44b4d 100644
--- a/src/derive.rs
+++ b/src/derive.rs
@@ -1,4 +1,5 @@
use super::*;
+use delimited::Delimited;
ast_struct! {
/// Struct or enum sent to a `proc_macro_derive` macro.
@@ -21,15 +22,25 @@
}
-ast_enum! {
+ast_enum_of_structs! {
/// Body of a derived struct or enum.
pub enum Body {
/// It's an enum.
- Enum(Vec<Variant>),
+ pub Enum(BodyEnum {
+ pub enum_token: tokens::Enum,
+ pub brace_token: tokens::Brace,
+ pub variants: Delimited<Variant, tokens::Comma>,
+ }),
/// It's a struct.
- Struct(VariantData),
+ pub Struct(BodyStruct {
+ pub data: VariantData,
+ pub struct_token: tokens::Struct,
+ pub semi_token: Option<tokens::Semi>,
+ }),
}
+
+ do_not_generate_to_tokens
}
#[cfg(feature = "parsing")]
@@ -48,7 +59,7 @@
id: ident >>
generics: generics >>
item: switch!(value!(which),
- "struct" => map!(struct_body, move |(wh, body)| DeriveInput {
+ "struct" => map!(struct_body, move |(wh, body, semi)| DeriveInput {
ident: id,
vis: vis,
attrs: attrs,
@@ -56,10 +67,14 @@
where_clause: wh,
.. generics
},
- body: Body::Struct(body),
+ body: Body::Struct(BodyStruct {
+ struct_token: tokens::Struct::default(),
+ data: body,
+ semi_token: semi,
+ }),
})
|
- "enum" => map!(enum_body, move |(wh, body)| DeriveInput {
+ "enum" => map!(enum_body, move |(wh, body, brace)| DeriveInput {
ident: id,
vis: vis,
attrs: attrs,
@@ -67,7 +82,11 @@
where_clause: wh,
.. generics
},
- body: Body::Enum(body),
+ body: Body::Enum(BodyEnum {
+ variants: body,
+ brace_token: brace,
+ enum_token: tokens::Enum::default(),
+ }),
})
) >>
(item)
@@ -88,38 +107,33 @@
}
self.vis.to_tokens(tokens);
match self.body {
- Body::Enum(_) => tokens.append("enum"),
- Body::Struct(_) => tokens.append("struct"),
+ Body::Enum(ref d) => d.enum_token.to_tokens(tokens),
+ Body::Struct(ref d) => d.struct_token.to_tokens(tokens),
}
self.ident.to_tokens(tokens);
self.generics.to_tokens(tokens);
match self.body {
- Body::Enum(ref variants) => {
+ Body::Enum(ref data) => {
self.generics.where_clause.to_tokens(tokens);
- tokens.append("{");
- for variant in variants {
- variant.to_tokens(tokens);
- tokens.append(",");
- }
- tokens.append("}");
+ data.brace_token.surround(tokens, |tokens| {
+ data.variants.to_tokens(tokens);
+ });
}
- Body::Struct(ref variant_data) => {
- match *variant_data {
- VariantData::Struct(_) => {
+ Body::Struct(ref data) => {
+ match data.data {
+ VariantData::Struct(..) => {
self.generics.where_clause.to_tokens(tokens);
- variant_data.to_tokens(tokens);
- // no semicolon
+ data.data.to_tokens(tokens);
}
- VariantData::Tuple(_) => {
- variant_data.to_tokens(tokens);
+ VariantData::Tuple(..) => {
+ data.data.to_tokens(tokens);
self.generics.where_clause.to_tokens(tokens);
- tokens.append(";");
}
VariantData::Unit => {
self.generics.where_clause.to_tokens(tokens);
- tokens.append(";");
}
}
+ data.semi_token.to_tokens(tokens);
}
}
}
diff --git a/src/expr.rs b/src/expr.rs
index 05f195a..2956ec9 100644
--- a/src/expr.rs
+++ b/src/expr.rs
@@ -1,4 +1,5 @@
use super::*;
+use delimited::Delimited;
ast_struct! {
/// An expression.
@@ -25,23 +26,27 @@
/// A `box x` expression.
pub Box(ExprBox {
pub expr: Box<Expr>,
+ pub box_token: tokens::Box,
}),
/// E.g. 'place <- val'.
pub InPlace(ExprInPlace {
pub place: Box<Expr>,
pub value: Box<Expr>,
+ pub in_token: tokens::In,
}),
/// An array, e.g. `[a, b, c, d]`.
pub Array(ExprArray {
- pub exprs: Vec<Expr>,
+ pub exprs: Delimited<Expr, tokens::Comma>,
+ pub bracket_token: tokens::Bracket,
}),
/// A function call.
pub Call(ExprCall {
pub func: Box<Expr>,
- pub args: Vec<Expr>,
+ pub args: Delimited<Expr, tokens::Comma>,
+ pub paren_token: tokens::Paren,
}),
/// A method call (`x.foo::<Bar, Baz>(a, b, c, d)`)
@@ -50,21 +55,25 @@
/// The vector of `Ty`s are the ascripted type parameters for the method
/// (within the angle brackets).
///
- /// The first element of the vector of `Expr`s is the expression that evaluates
- /// to the object on which the method is being called on (the receiver),
- /// and the remaining elements are the rest of the arguments.
- ///
/// Thus, `x.foo::<Bar, Baz>(a, b, c, d)` is represented as
/// `ExprKind::MethodCall(foo, [Bar, Baz], [x, a, b, c, d])`.
pub MethodCall(ExprMethodCall {
+ pub expr: Box<Expr>,
pub method: Ident,
- pub typarams: Vec<Ty>,
- pub args: Vec<Expr>,
+ pub typarams: Delimited<Ty, tokens::Comma>,
+ pub args: Delimited<Expr, tokens::Comma>,
+ pub paren_token: tokens::Paren,
+ pub dot_token: tokens::Dot,
+ pub lt_token: Option<tokens::Lt>,
+ pub colon2_token: Option<tokens::Colon2>,
+ pub gt_token: Option<tokens::Gt>,
}),
/// A tuple, e.g. `(a, b, c, d)`.
pub Tup(ExprTup {
- pub args: Vec<Expr>,
+ pub args: Delimited<Expr, tokens::Comma>,
+ pub paren_token: tokens::Paren,
+ pub lone_comma: Option<tokens::Comma>,
}),
/// A binary operation, e.g. `a + b`, `a * b`.
@@ -86,12 +95,14 @@
/// A cast, e.g. `foo as f64`.
pub Cast(ExprCast {
pub expr: Box<Expr>,
+ pub as_token: tokens::As,
pub ty: Box<Ty>,
}),
/// A type ascription, e.g. `foo: f64`.
pub Type(ExprType {
pub expr: Box<Expr>,
+ pub colon_token: tokens::Colon,
pub ty: Box<Ty>,
}),
@@ -102,6 +113,8 @@
pub cond: Box<Expr>,
pub if_true: Block,
pub if_false: Option<Box<Expr>>,
+ pub if_token: tokens::If,
+ pub else_token: Option<tokens::Else>,
}),
/// An `if let` expression with an optional else block
@@ -114,6 +127,10 @@
pub expr: Box<Expr>,
pub if_true: Block,
pub if_false: Option<Box<Expr>>,
+ pub if_token: tokens::If,
+ pub let_token: tokens::Let,
+ pub eq_token: tokens::Eq,
+ pub else_token: Option<tokens::Else>,
}),
/// A while loop, with an optional label
@@ -123,6 +140,8 @@
pub cond: Box<Expr>,
pub body: Block,
pub label: Option<Ident>,
+ pub colon_token: Option<tokens::Colon>,
+ pub while_token: tokens::While,
}),
/// A while-let loop, with an optional label.
@@ -135,6 +154,10 @@
pub expr: Box<Expr>,
pub body: Block,
pub label: Option<Ident>,
+ pub colon_token: Option<tokens::Colon>,
+ pub while_token: tokens::While,
+ pub let_token: tokens::Let,
+ pub eq_token: tokens::Eq,
}),
/// A for loop, with an optional label.
@@ -147,6 +170,9 @@
pub expr: Box<Expr>,
pub body: Block,
pub label: Option<Ident>,
+ pub for_token: tokens::For,
+ pub colon_token: Option<tokens::Colon>,
+ pub in_token: tokens::In,
}),
/// Conditionless loop with an optional label.
@@ -155,10 +181,14 @@
pub Loop(ExprLoop {
pub body: Block,
pub label: Option<Ident>,
+ pub loop_token: tokens::Loop,
+ pub colon_token: Option<tokens::Colon>,
}),
/// A `match` block.
pub Match(ExprMatch {
+ pub match_token: tokens::Match,
+ pub brace_token: tokens::Brace,
pub expr: Box<Expr>,
pub arms: Vec<Arm>,
}),
@@ -168,6 +198,8 @@
pub capture: CaptureBy,
pub decl: Box<FnDecl>,
pub body: Box<Expr>,
+ pub or1_token: tokens::Or,
+ pub or2_token: tokens::Or,
}),
/// A block (`{ ... }` or `unsafe { ... }`)
@@ -180,6 +212,7 @@
pub Assign(ExprAssign {
pub left: Box<Expr>,
pub right: Box<Expr>,
+ pub eq_token: tokens::Eq,
}),
/// An assignment with an operator
@@ -195,6 +228,7 @@
pub Field(ExprField {
pub expr: Box<Expr>,
pub field: Ident,
+ pub dot_token: tokens::Dot,
}),
/// Access of an unnamed field of a struct or tuple-struct
@@ -202,13 +236,15 @@
/// For example, `foo.0`.
pub TupField(ExprTupField {
pub expr: Box<Expr>,
- pub field: usize,
+ pub field: Lit,
+ pub dot_token: tokens::Dot,
}),
/// An indexing operation (`foo[2]`)
pub Index(ExprIndex {
pub expr: Box<Expr>,
pub index: Box<Expr>,
+ pub bracket_token: tokens::Bracket,
}),
/// A range (`1..2`, `1..`, `..2`, `1...2`, `1...`, `...2`)
@@ -230,6 +266,7 @@
/// A referencing operation (`&a` or `&mut a`)
pub AddrOf(ExprAddrOf {
+ pub and_token: tokens::And,
pub mutbl: Mutability,
pub expr: Box<Expr>,
}),
@@ -238,16 +275,19 @@
pub Break(ExprBreak {
pub label: Option<Ident>,
pub expr: Option<Box<Expr>>,
+ pub break_token: tokens::Break,
}),
/// A `continue`, with an optional label
pub Continue(ExprContinue {
pub label: Option<Ident>,
+ pub continue_token: tokens::Continue,
}),
/// A `return`, with an optional value to be returned
pub Ret(ExprRet {
pub expr: Option<Box<Expr>>,
+ pub return_token: tokens::Return,
}),
/// A macro invocation; pre-expansion
@@ -259,8 +299,10 @@
/// `Foo {x: 1, .. base}`, where `base` is the `Option<Expr>`.
pub Struct(ExprStruct {
pub path: Path,
- pub fields: Vec<FieldValue>,
+ pub fields: Delimited<FieldValue, tokens::Comma>,
pub rest: Option<Box<Expr>>,
+ pub dot2_token: Option<tokens::Dot2>,
+ pub brace_token: tokens::Brace,
}),
/// An array literal constructed from one repeated element.
@@ -268,6 +310,8 @@
/// For example, `[1; 5]`. The first expression is the element
/// to be repeated; the second is the number of times to repeat it.
pub Repeat(ExprRepeat {
+ pub bracket_token: tokens::Bracket,
+ pub semi_token: tokens::Semi,
pub expr: Box<Expr>,
pub amt: Box<Expr>,
}),
@@ -275,17 +319,21 @@
/// No-op: used solely so we can pretty-print faithfully
pub Paren(ExprParen {
pub expr: Box<Expr>,
+ pub paren_token: tokens::Paren,
}),
/// `expr?`
pub Try(ExprTry {
pub expr: Box<Expr>,
+ pub question_token: tokens::Question,
}),
/// A catch expression.
///
/// E.g. `do catch { block }`
pub Catch(ExprCatch {
+ pub do_token: tokens::Do,
+ pub catch_token: tokens::Catch,
pub block: Block,
}),
}
@@ -306,6 +354,8 @@
/// Attributes tagged on the field.
pub attrs: Vec<Attribute>,
+
+ pub colon_token: Option<tokens::Colon>,
}
}
@@ -314,6 +364,7 @@
///
/// E.g. `{ .. }` as in `fn foo() { .. }`
pub struct Block {
+ pub brace_token: tokens::Brace,
/// Statements in a block
pub stmts: Vec<Stmt>,
}
@@ -332,7 +383,7 @@
Expr(Box<Expr>),
/// Expression with trailing semicolon;
- Semi(Box<Expr>),
+ Semi(Box<Expr>, tokens::Semi),
/// Macro invocation.
Mac(Box<(Mac, MacStmtStyle, Vec<Attribute>)>),
@@ -345,7 +396,7 @@
pub enum MacStmtStyle {
/// The macro statement had a trailing semicolon, e.g. `foo! { ... };`
/// `foo!(...);`, `foo![...];`
- Semicolon,
+ Semicolon(tokens::Semi),
/// The macro statement had braces; e.g. foo! { ... }
Braces,
@@ -360,6 +411,11 @@
ast_struct! {
/// Local represents a `let` statement, e.g., `let <pat>:<ty> = <expr>;`
pub struct Local {
+ pub let_token: tokens::Let,
+ pub colon_token: Option<tokens::Colon>,
+ pub eq_token: Option<tokens::Eq>,
+ pub semi_token: tokens::Semi,
+
pub pat: Box<Pat>,
pub ty: Option<Box<Ty>>,
@@ -369,52 +425,95 @@
}
}
-ast_enum! {
+ast_enum_of_structs! {
// Clippy false positive
// https://github.com/Manishearth/rust-clippy/issues/1241
#[cfg_attr(feature = "cargo-clippy", allow(enum_variant_names))]
pub enum Pat {
/// Represents a wildcard pattern (`_`)
- Wild,
+ pub Wild(PatWild {
+ pub underscore_token: tokens::Underscore,
+ }),
/// A `Pat::Ident` may either be a new bound variable (`ref mut binding @ OPT_SUBPATTERN`),
/// or a unit struct/variant pattern, or a const pattern (in the last two cases the third
/// field must be `None`). Disambiguation cannot be done with parser alone, so it happens
/// during name resolution.
- Ident(BindingMode, Ident, Option<Box<Pat>>),
+ pub Ident(PatIdent {
+ pub mode: BindingMode,
+ pub ident: Ident,
+ pub subpat: Option<Box<Pat>>,
+ pub at_token: Option<tokens::At>,
+ }),
/// A struct or struct variant pattern, e.g. `Variant {x, y, ..}`.
/// The `bool` is `true` in the presence of a `..`.
- Struct(Path, Vec<FieldPat>, bool),
+ pub Struct(PatStruct {
+ pub path: Path,
+ pub fields: Delimited<FieldPat, tokens::Comma>,
+ pub brace_token: tokens::Brace,
+ pub dot2_token: Option<tokens::Dot2>,
+ }),
/// A tuple struct/variant pattern `Variant(x, y, .., z)`.
/// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
/// 0 <= position <= subpats.len()
- TupleStruct(Path, Vec<Pat>, Option<usize>),
+ pub TupleStruct(PatTupleStruct {
+ pub path: Path,
+ pub pat: PatTuple,
+ }),
/// A possibly qualified path pattern.
/// Unquailfied path patterns `A::B::C` can legally refer to variants, structs, constants
/// or associated constants. Quailfied path patterns `<A>::B::C`/`<A as Trait>::B::C` can
/// only legally refer to associated constants.
- Path(Option<QSelf>, Path),
+ pub Path(PatPath {
+ pub qself: Option<QSelf>,
+ pub path: Path,
+ }),
/// A tuple pattern `(a, b)`.
/// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
/// 0 <= position <= subpats.len()
- Tuple(Vec<Pat>, Option<usize>),
+ pub Tuple(PatTuple {
+ pub pats: Delimited<Pat, tokens::Comma>,
+ pub dots_pos: Option<usize>,
+ pub paren_token: tokens::Paren,
+ pub dot2_token: Option<tokens::Dot2>,
+ pub comma_token: Option<tokens::Comma>,
+ }),
/// A `box` pattern
- Box(Box<Pat>),
+ pub Box(PatBox {
+ pub pat: Box<Pat>,
+ pub box_token: tokens::Box,
+ }),
/// A reference pattern, e.g. `&mut (a, b)`
- Ref(Box<Pat>, Mutability),
+ pub Ref(PatRef {
+ pub pat: Box<Pat>,
+ pub mutbl: Mutability,
+ pub and_token: tokens::And,
+ }),
/// A literal
- Lit(Box<Expr>),
+ pub Lit(PatLit {
+ pub expr: Box<Expr>,
+ }),
/// A range pattern, e.g. `1...2`
- Range(Box<Expr>, Box<Expr>, RangeLimits),
+ pub Range(PatRange {
+ pub lo: Box<Expr>,
+ pub hi: Box<Expr>,
+ pub limits: RangeLimits,
+ }),
/// `[a, b, ..i, y, z]` is represented as:
- /// `Pat::Slice(box [a, b], Some(i), box [y, z])`
- Slice(Vec<Pat>, Option<Box<Pat>>, Vec<Pat>),
+ pub Slice(PatSlice {
+ pub front: Delimited<Pat, tokens::Comma>,
+ pub middle: Option<Box<Pat>>,
+ pub back: Delimited<Pat, tokens::Comma>,
+ pub dot2_token: Option<tokens::Dot2>,
+ pub comma_token: Option<tokens::Comma>,
+ pub bracket_token: tokens::Bracket,
+ }),
/// A macro pattern; pre-expansion
- Mac(Mac),
+ pub Mac(Mac),
}
}
@@ -431,9 +530,12 @@
/// ```
pub struct Arm {
pub attrs: Vec<Attribute>,
- pub pats: Vec<Pat>,
+ pub pats: Delimited<Pat, tokens::Or>,
+ pub if_token: Option<tokens::If>,
pub guard: Option<Box<Expr>>,
+ pub rocket_token: tokens::Rocket,
pub body: Box<Expr>,
+ pub comma: Option<tokens::Comma>,
}
}
@@ -441,7 +543,7 @@
/// A capture clause
#[cfg_attr(feature = "clone-impls", derive(Copy))]
pub enum CaptureBy {
- Value,
+ Value(tokens::Move),
Ref,
}
}
@@ -451,9 +553,9 @@
#[cfg_attr(feature = "clone-impls", derive(Copy))]
pub enum RangeLimits {
/// Inclusive at the beginning, exclusive at the end
- HalfOpen,
+ HalfOpen(tokens::Dot2),
/// Inclusive at the beginning and end
- Closed,
+ Closed(tokens::Dot3),
}
}
@@ -469,6 +571,7 @@
/// The pattern the field is destructured to
pub pat: Box<Pat>,
pub is_shorthand: bool,
+ pub colon_token: Option<tokens::Colon>,
pub attrs: Vec<Attribute>,
}
}
@@ -476,7 +579,7 @@
ast_enum! {
#[cfg_attr(feature = "clone-impls", derive(Copy))]
pub enum BindingMode {
- ByRef(Mutability),
+ ByRef(tokens::Ref, Mutability),
ByValue(Mutability),
}
}
@@ -484,18 +587,20 @@
#[cfg(feature = "parsing")]
pub mod parsing {
use super::*;
- use {BinOp, Delimited, DelimToken, FnArg, FnDecl, FunctionRetTy, Ident, Lifetime, Mac,
+ use {BinOp, FnArg, FnDecl, FunctionRetTy, Ident, Lifetime, Mac,
TokenTree, Ty, UnOp, Unsafety, ArgCaptured, TyInfer};
use attr::parsing::outer_attr;
use generics::parsing::lifetime;
use ident::parsing::{ident, wordlike};
use item::parsing::item;
- use lit::parsing::{digits, lit};
- use mac::parsing::{mac, token_trees};
+ use lit::parsing::lit;
+ use mac::parsing::{mac, token_stream};
use synom::IResult::{self, Error};
use op::parsing::{assign_op, binop, unop};
use ty::parsing::{mutability, path, qpath, ty, unsafety};
+ use proc_macro2::{self, TokenKind, Delimiter};
+
// Struct literals are ambiguous in certain positions
// https://github.com/rust-lang/rfcs/pull/92
macro_rules! named_ambiguous_expr {
@@ -571,20 +676,18 @@
) >>
many0!(alt!(
tap!(args: and_call => {
+ let (args, paren) = args;
e = ExprCall {
func: Box::new(e.into()),
args: args,
+ paren_token: paren,
}.into();
})
|
tap!(more: and_method_call => {
- let (method, ascript, mut args) = more;
- args.insert(0, e.into());
- e = ExprMethodCall {
- method: method,
- typarams: ascript,
- args: args,
- }.into();
+ let mut call = more;
+ call.expr = Box::new(e.into());
+ e = call.into();
})
|
tap!(more: call!(and_binary, allow_struct) => {
@@ -597,22 +700,28 @@
})
|
tap!(ty: and_cast => {
+ let (ty, token) = ty;
e = ExprCast {
expr: Box::new(e.into()),
ty: Box::new(ty),
+ as_token: token,
}.into();
})
|
tap!(ty: and_ascription => {
+ let (ty, token) = ty;
e = ExprType {
expr: Box::new(e.into()),
ty: Box::new(ty),
+ colon_token: token,
}.into();
})
|
tap!(v: call!(and_assign, allow_struct) => {
+ let (v, token) = v;
e = ExprAssign {
left: Box::new(e.into()),
+ eq_token: token,
right: Box::new(v),
}.into();
})
@@ -627,22 +736,28 @@
})
|
tap!(field: and_field => {
+ let (field, token) = field;
e = ExprField {
expr: Box::new(e.into()),
field: field,
+ dot_token: token,
}.into();
})
|
tap!(field: and_tup_field => {
+ let (field, token) = field;
e = ExprTupField {
expr: Box::new(e.into()),
- field: field as usize,
+ field: field,
+ dot_token: token,
}.into();
})
|
tap!(i: and_index => {
+ let (i, token) = i;
e = ExprIndex {
expr: Box::new(e.into()),
+ bracket_token: token,
index: Box::new(i),
}.into();
})
@@ -657,7 +772,10 @@
})
|
tap!(_try: punct!("?") => {
- e = ExprTry { expr: Box::new(e.into()) }.into();
+ e = ExprTry {
+ expr: Box::new(e.into()),
+ question_token: tokens::Question::default(),
+ }.into();
})
)) >>
(e.into())
@@ -670,13 +788,19 @@
punct!("(") >>
e: expr >>
punct!(")") >>
- (ExprParen { expr: Box::new(e) }.into())
+ (ExprParen {
+ expr: Box::new(e),
+ paren_token: tokens::Paren::default(),
+ }.into())
));
named_ambiguous_expr!(expr_box -> ExprKind, allow_struct, do_parse!(
keyword!("box") >>
inner: ambiguous_expr!(allow_struct) >>
- (ExprBox { expr: Box::new(inner) }.into())
+ (ExprBox {
+ expr: Box::new(inner),
+ box_token: tokens::Box::default(),
+ }.into())
));
named!(expr_in_place -> ExprKind, do_parse!(
@@ -686,11 +810,15 @@
value: within_block >>
punct!("}") >>
(ExprInPlace {
+ in_token: tokens::In::default(),
place: Box::new(place),
value: Box::new(Expr {
node: ExprBlock {
unsafety: Unsafety::Normal,
- block: Block { stmts: value, },
+ block: Block {
+ stmts: value,
+ brace_token: tokens::Brace::default(),
+ },
}.into(),
attrs: Vec::new(),
}),
@@ -699,40 +827,66 @@
named!(expr_array -> ExprKind, do_parse!(
punct!("[") >>
- elems: terminated_list!(punct!(","), expr) >>
+ elems: terminated_list!(map!(punct!(","), |_| tokens::Comma::default()),
+ expr) >>
punct!("]") >>
- (ExprArray { exprs: elems }.into())
+ (ExprArray {
+ exprs: elems,
+ bracket_token: tokens::Bracket::default(),
+ }.into())
));
- named!(and_call -> Vec<Expr>, do_parse!(
+ named!(and_call -> (Delimited<Expr, tokens::Comma>, tokens::Paren), do_parse!(
punct!("(") >>
- args: terminated_list!(punct!(","), expr) >>
+ args: terminated_list!(map!(punct!(","), |_| tokens::Comma::default()),
+ expr) >>
punct!(")") >>
- (args)
+ (args, tokens::Paren::default())
));
- named!(and_method_call -> (Ident, Vec<Ty>, Vec<Expr>), do_parse!(
+ named!(and_method_call -> ExprMethodCall, do_parse!(
punct!(".") >>
method: ident >>
- ascript: opt_vec!(preceded!(
- punct!("::"),
- delimited!(
- punct!("<"),
- terminated_list!(punct!(","), ty),
- punct!(">")
- )
+ typarams: option!(do_parse!(
+ punct!("::") >>
+ punct!("<") >>
+ tys: terminated_list!(map!(punct!(","), |_| tokens::Comma::default()),
+ ty) >>
+ punct!(">") >>
+ (tys)
)) >>
punct!("(") >>
- args: terminated_list!(punct!(","), expr) >>
+ args: terminated_list!(map!(punct!(","), |_| tokens::Comma::default()),
+ expr) >>
punct!(")") >>
- (method, ascript, args)
+ (ExprMethodCall {
+ // this expr will get overwritten after being returned
+ expr: Box::new(ExprKind::Lit(Lit {
+ span: Span::default(),
+ value: LitKind::Bool(false),
+ }).into()),
+
+ method: method,
+ args: args,
+ paren_token: tokens::Paren::default(),
+ dot_token: tokens::Dot::default(),
+ lt_token: typarams.as_ref().map(|_| tokens::Lt::default()),
+ gt_token: typarams.as_ref().map(|_| tokens::Gt::default()),
+ colon2_token: typarams.as_ref().map(|_| tokens::Colon2::default()),
+ typarams: typarams.unwrap_or_default(),
+ })
));
named!(expr_tup -> ExprKind, do_parse!(
punct!("(") >>
- elems: terminated_list!(punct!(","), expr) >>
+ elems: terminated_list!(map!(punct!(","), |_| tokens::Comma::default()),
+ expr) >>
punct!(")") >>
- (ExprTup { args: elems }.into())
+ (ExprTup {
+ args: elems,
+ paren_token: tokens::Paren::default(),
+ lone_comma: None, // TODO: parse this
+ }.into())
));
named_ambiguous_expr!(and_binary -> (BinOp, Expr), allow_struct, tuple!(
@@ -748,16 +902,17 @@
named!(expr_lit -> ExprKind, map!(lit, ExprKind::Lit));
- named!(and_cast -> Ty, do_parse!(
+ named!(and_cast -> (Ty, tokens::As), do_parse!(
keyword!("as") >>
ty: ty >>
- (ty)
+ (ty, tokens::As::default())
));
- named!(and_ascription -> Ty, preceded!(punct!(":"), ty));
+ named!(and_ascription -> (Ty, tokens::Colon),
+ preceded!(punct!(":"), map!(ty, |t| (t, tokens::Colon::default()))));
enum Cond {
- Let(Pat, Expr),
+ Let(Pat, Expr, tokens::Eq, tokens::Let),
Expr(Expr),
}
@@ -767,7 +922,7 @@
pat: pat >>
punct!("=") >>
value: expr_no_struct >>
- (Cond::Let(pat, value))
+ (Cond::Let(pat, value, tokens::Eq::default(), tokens::Let::default()))
)
|
map!(expr_no_struct, Cond::Expr)
@@ -790,25 +945,36 @@
punct!("}") >>
(ExprKind::Block(ExprBlock {
unsafety: Unsafety::Normal,
- block: Block { stmts: else_block },
+ block: Block {
+ stmts: else_block,
+ brace_token: tokens::Brace::default(),
+ },
}).into())
)
)
)) >>
(match cond {
- Cond::Let(pat, expr) => ExprIfLet {
+ Cond::Let(pat, expr, eq_token, let_token) => ExprIfLet {
pat: Box::new(pat),
expr: Box::new(expr),
+ eq_token: eq_token,
+ let_token: let_token,
if_true: Block {
stmts: then_block,
+ brace_token: tokens::Brace::default(),
},
+ if_token: tokens::If::default(),
+ else_token: else_block.as_ref().map(|_| tokens::Else::default()),
if_false: else_block.map(|els| Box::new(els.into())),
}.into(),
Cond::Expr(cond) => ExprIf {
cond: Box::new(cond),
if_true: Block {
stmts: then_block,
+ brace_token: tokens::Brace::default(),
},
+ if_token: tokens::If::default(),
+ else_token: else_block.as_ref().map(|_| tokens::Else::default()),
if_false: else_block.map(|els| Box::new(els.into())),
}.into(),
})
@@ -822,6 +988,9 @@
expr: expr_no_struct >>
loop_block: block >>
(ExprForLoop {
+ for_token: tokens::For::default(),
+ in_token: tokens::In::default(),
+ colon_token: lbl.as_ref().map(|_| tokens::Colon::default()),
pat: Box::new(pat),
expr: Box::new(expr),
body: loop_block,
@@ -833,7 +1002,12 @@
lbl: option!(terminated!(label, punct!(":"))) >>
keyword!("loop") >>
loop_block: block >>
- (ExprLoop { body: loop_block, label: lbl }.into())
+ (ExprLoop {
+ loop_token: tokens::Loop::default(),
+ colon_token: lbl.as_ref().map(|_| tokens::Colon::default()),
+ body: loop_block,
+ label: lbl,
+ }.into())
));
named!(expr_match -> ExprKind, do_parse!(
@@ -850,7 +1024,14 @@
punct!("}") >>
(ExprMatch {
expr: Box::new(obj),
+ match_token: tokens::Match::default(),
+ brace_token: tokens::Brace::default(),
arms: {
+ for arm in &mut arms {
+ if arm_requires_comma(arm) {
+ arm.comma = Some(tokens::Comma::default());
+ }
+ }
arms.extend(last_arm);
arms
},
@@ -861,7 +1042,11 @@
keyword!("do") >>
keyword!("catch") >>
catch_block: block >>
- (ExprCatch { block: catch_block }.into())
+ (ExprCatch {
+ block: catch_block,
+ do_token: tokens::Do::default(),
+ catch_token: tokens::Catch::default(),
+ }.into())
));
fn arm_requires_comma(arm: &Arm) -> bool {
@@ -874,7 +1059,8 @@
named!(match_arm -> Arm, do_parse!(
attrs: many0!(outer_attr) >>
- pats: separated_nonempty_list!(punct!("|"), pat) >>
+ pats: separated_nonempty_list!(map!(punct!("|"), |_| tokens::Or::default()),
+ pat) >>
guard: option!(preceded!(keyword!("if"), expr)) >>
punct!("=>") >>
body: alt!(
@@ -888,24 +1074,29 @@
expr
) >>
(Arm {
+ rocket_token: tokens::Rocket::default(),
+ if_token: guard.as_ref().map(|_| tokens::If::default()),
attrs: attrs,
pats: pats,
guard: guard.map(Box::new),
body: Box::new(body),
+ comma: None,
})
));
named_ambiguous_expr!(expr_closure -> ExprKind, allow_struct, do_parse!(
capture: capture_by >>
punct!("|") >>
- inputs: terminated_list!(punct!(","), closure_arg) >>
+ inputs: terminated_list!(map!(punct!(","), |_| tokens::Comma::default()),
+ closure_arg) >>
punct!("|") >>
ret_and_body: alt!(
do_parse!(
punct!("->") >>
ty: ty >>
body: block >>
- (FunctionRetTy::Ty(ty), ExprKind::Block(ExprBlock {
+ (FunctionRetTy::Ty(ty, tokens::RArrow::default()),
+ ExprKind::Block(ExprBlock {
unsafety: Unsafety::Normal,
block: body,
}).into())
@@ -915,10 +1106,16 @@
) >>
(ExprClosure {
capture: capture,
+ or1_token: tokens::Or::default(),
+ or2_token: tokens::Or::default(),
decl: Box::new(FnDecl {
inputs: inputs,
output: ret_and_body.0,
variadic: false,
+ dot_tokens: None,
+ fn_token: tokens::Fn::default(),
+ generics: Generics::default(),
+ paren_token: tokens::Paren::default(),
}),
body: Box::new(ret_and_body.1),
}.into())
@@ -929,7 +1126,10 @@
ty: option!(preceded!(punct!(":"), ty)) >>
(ArgCaptured {
pat: pat,
- ty: ty.unwrap_or_else(|| TyInfer {}.into()),
+ colon_token: tokens::Colon::default(),
+ ty: ty.unwrap_or_else(|| TyInfer {
+ underscore_token: tokens::Underscore::default(),
+ }.into()),
}.into())
));
@@ -939,13 +1139,19 @@
cond: cond >>
while_block: block >>
(match cond {
- Cond::Let(pat, expr) => ExprWhileLet {
+ Cond::Let(pat, expr, eq_token, let_token) => ExprWhileLet {
+ eq_token: eq_token,
+ let_token: let_token,
+ while_token: tokens::While::default(),
+ colon_token: lbl.as_ref().map(|_| tokens::Colon::default()),
pat: Box::new(pat),
expr: Box::new(expr),
body: while_block,
label: lbl,
}.into(),
Cond::Expr(cond) => ExprWhile {
+ while_token: tokens::While::default(),
+ colon_token: lbl.as_ref().map(|_| tokens::Colon::default()),
cond: Box::new(cond),
body: while_block,
label: lbl,
@@ -956,38 +1162,54 @@
named!(expr_continue -> ExprKind, do_parse!(
keyword!("continue") >>
lbl: option!(label) >>
- (ExprContinue { label: lbl }.into())
+ (ExprContinue {
+ continue_token: tokens::Continue::default(),
+ label: lbl,
+ }.into())
));
named_ambiguous_expr!(expr_break -> ExprKind, allow_struct, do_parse!(
keyword!("break") >>
lbl: option!(label) >>
val: option!(call!(ambiguous_expr, allow_struct, false)) >>
- (ExprBreak { label: lbl, expr: val.map(Box::new) }.into())
+ (ExprBreak {
+ label: lbl,
+ expr: val.map(Box::new),
+ break_token: tokens::Break::default(),
+ }.into())
));
named_ambiguous_expr!(expr_ret -> ExprKind, allow_struct, do_parse!(
keyword!("return") >>
ret_value: option!(ambiguous_expr!(allow_struct)) >>
- (ExprRet { expr: ret_value.map(Box::new) }.into())
+ (ExprRet {
+ expr: ret_value.map(Box::new),
+ return_token: tokens::Return::default(),
+ }.into())
));
named!(expr_struct -> ExprKind, do_parse!(
path: path >>
punct!("{") >>
- fields: separated_list!(punct!(","), field_value) >>
- base: option!(do_parse!(
- cond!(!fields.is_empty(), punct!(",")) >>
- punct!("..") >>
- base: expr >>
- (base)
- )) >>
- cond!(!fields.is_empty() && base.is_none(), option!(punct!(","))) >>
+ fields: terminated_list!(map!(punct!(","), |_| tokens::Comma::default()),
+ field_value) >>
+ base: option!(
+ cond!(fields.is_empty() || fields.trailing_delim(),
+ do_parse!(
+ punct!("..") >>
+ base: expr >>
+ (base)
+ )
+ )
+ ) >>
punct!("}") >>
(ExprStruct {
+ brace_token: tokens::Brace::default(),
path: path,
fields: fields,
- rest: base.map(Box::new),
+ dot2_token: base.as_ref().and_then(|b| b.as_ref())
+ .map(|_| tokens::Dot2::default()),
+ rest: base.and_then(|b| b.map(Box::new)),
}.into())
));
@@ -1001,6 +1223,7 @@
expr: value,
is_shorthand: false,
attrs: Vec::new(),
+ colon_token: Some(tokens::Colon::default()),
})
)
|
@@ -1009,6 +1232,7 @@
expr: ExprKind::Path(ExprPath { qself: None, path: name.into() }).into(),
is_shorthand: true,
attrs: Vec::new(),
+ colon_token: None,
})
));
@@ -1018,7 +1242,12 @@
punct!(";") >>
times: expr >>
punct!("]") >>
- (ExprRepeat { expr: Box::new(value), amt: Box::new(times) }.into())
+ (ExprRepeat {
+ expr: Box::new(value),
+ amt: Box::new(times),
+ bracket_token: tokens::Bracket::default(),
+ semi_token: tokens::Semi::default(),
+ }.into())
));
named!(expr_block -> ExprKind, do_parse!(
@@ -1026,7 +1255,7 @@
b: block >>
(ExprBlock {
unsafety: rules,
- block: Block { stmts: b.stmts },
+ block: b,
}.into())
));
@@ -1037,9 +1266,9 @@
));
named!(range_limits -> RangeLimits, alt!(
- punct!("...") => { |_| RangeLimits::Closed }
+ punct!("...") => { |_| RangeLimits::Closed(tokens::Dot3::default()) }
|
- punct!("..") => { |_| RangeLimits::HalfOpen }
+ punct!("..") => { |_| RangeLimits::HalfOpen(tokens::Dot2::default()) }
));
named!(expr_path -> ExprKind, map!(qpath, |(qself, path)| {
@@ -1050,12 +1279,16 @@
punct!("&") >>
mutability: mutability >>
expr: ambiguous_expr!(allow_struct) >>
- (ExprAddrOf { mutbl: mutability, expr: Box::new(expr) }.into())
+ (ExprAddrOf {
+ mutbl: mutability,
+ expr: Box::new(expr),
+ and_token: tokens::And::default(),
+ }.into())
));
- named_ambiguous_expr!(and_assign -> Expr, allow_struct, preceded!(
+ named_ambiguous_expr!(and_assign -> (Expr, tokens::Eq), allow_struct, preceded!(
punct!("="),
- ambiguous_expr!(allow_struct)
+ map!(ambiguous_expr!(allow_struct), |t| (t, tokens::Eq::default()))
));
named_ambiguous_expr!(and_assign_op -> (BinOp, Expr), allow_struct, tuple!(
@@ -1063,11 +1296,15 @@
ambiguous_expr!(allow_struct)
));
- named!(and_field -> Ident, preceded!(punct!("."), ident));
+ named!(and_field -> (Ident, tokens::Dot),
+ preceded!(punct!("."), map!(ident, |t| (t, tokens::Dot::default()))));
- named!(and_tup_field -> u64, preceded!(punct!("."), digits));
+ named!(and_tup_field -> (Lit, tokens::Dot),
+ preceded!(punct!("."), map!(lit, |l| (l, tokens::Dot::default()))));
- named!(and_index -> Expr, delimited!(punct!("["), expr, punct!("]")));
+ named!(and_index -> (Expr, tokens::Bracket),
+ map!(delimited!(punct!("["), expr, punct!("]")),
+ |t| (t, tokens::Bracket::default())));
named_ambiguous_expr!(and_range -> (RangeLimits, Option<Expr>), allow_struct, tuple!(
range_limits,
@@ -1080,6 +1317,7 @@
punct!("}") >>
(Block {
stmts: stmts,
+ brace_token: tokens::Brace::default(),
})
));
@@ -1113,19 +1351,20 @@
// Only parse braces here; paren and bracket will get parsed as
// expression statements
punct!("{") >>
- tts: token_trees >>
+ ts: token_stream >>
punct!("}") >>
semi: option!(punct!(";")) >>
(Stmt::Mac(Box::new((
Mac {
path: what,
- tts: vec![TokenTree::Delimited(Delimited {
- delim: DelimToken::Brace,
- tts: tts,
+ bang_token: tokens::Bang::default(),
+ tokens: vec![TokenTree(proc_macro2::TokenTree {
+ span: Default::default(),
+ kind: TokenKind::Sequence(Delimiter::Brace, ts),
})],
},
if semi.is_some() {
- MacStmtStyle::Semicolon
+ MacStmtStyle::Semicolon(tokens::Semi::default())
} else {
MacStmtStyle::Braces
},
@@ -1141,6 +1380,10 @@
init: option!(preceded!(punct!("="), expr)) >>
punct!(";") >>
(Stmt::Local(Box::new(Local {
+ let_token: tokens::Let::default(),
+ semi_token: tokens::Semi::default(),
+ colon_token: ty.as_ref().map(|_| tokens::Colon::default()),
+ eq_token: init.as_ref().map(|_| tokens::Eq::default()),
pat: Box::new(pat),
ty: ty.map(Box::new),
init: init.map(Box::new),
@@ -1172,7 +1415,7 @@
({
e.attrs = attrs;
if semi.is_some() {
- Stmt::Semi(Box::new(e))
+ Stmt::Semi(Box::new(e), tokens::Semi::default())
} else if requires_semi(&e) {
return Error;
} else {
@@ -1200,7 +1443,7 @@
|
pat_path
|
- pat_tuple
+ map!(pat_tuple, |t: PatTuple| t.into())
|
pat_ref
|
@@ -1209,12 +1452,17 @@
named!(pat_mac -> Pat, map!(mac, Pat::Mac));
- named!(pat_wild -> Pat, map!(keyword!("_"), |_| Pat::Wild));
+ named!(pat_wild -> Pat, map!(keyword!("_"), |_| {
+ PatWild { underscore_token: tokens::Underscore::default() }.into()
+ }));
named!(pat_box -> Pat, do_parse!(
keyword!("box") >>
pat: pat >>
- (Pat::Box(Box::new(pat)))
+ (PatBox {
+ pat: Box::new(pat),
+ box_token: tokens::Box::default(),
+ }.into())
));
named!(pat_ident -> Pat, do_parse!(
@@ -1228,34 +1476,43 @@
not!(punct!("<")) >>
not!(punct!("::")) >>
subpat: option!(preceded!(punct!("@"), pat)) >>
- (Pat::Ident(
- if mode.is_some() {
- BindingMode::ByRef(mutability)
+ (PatIdent {
+ mode: if mode.is_some() {
+ BindingMode::ByRef(tokens::Ref::default(), mutability)
} else {
BindingMode::ByValue(mutability)
},
- name,
- subpat.map(Box::new),
- ))
+ ident: name,
+ at_token: subpat.as_ref().map(|_| tokens::At::default()),
+ subpat: subpat.map(Box::new),
+ }.into())
));
named!(pat_tuple_struct -> Pat, do_parse!(
path: path >>
- tuple: pat_tuple_helper >>
- (Pat::TupleStruct(path, tuple.0, tuple.1))
+ tuple: pat_tuple >>
+ (PatTupleStruct {
+ path: path,
+ pat: tuple,
+ }.into())
));
named!(pat_struct -> Pat, do_parse!(
path: path >>
punct!("{") >>
- fields: separated_list!(punct!(","), field_pat) >>
- more: option!(preceded!(
- cond!(!fields.is_empty(), punct!(",")),
- punct!("..")
- )) >>
- cond!(!fields.is_empty() && more.is_none(), option!(punct!(","))) >>
+ fields: terminated_list!(map!(punct!(","), |_| tokens::Comma::default()),
+ field_pat) >>
+ base: option!(
+ cond!(fields.is_empty() || fields.trailing_delim(),
+ punct!(".."))
+ ) >>
punct!("}") >>
- (Pat::Struct(path, fields, more.is_some()))
+ (PatStruct {
+ path: path,
+ fields: fields,
+ brace_token: tokens::Brace::default(),
+ dot2_token: base.and_then(|m| m).map(|_| tokens::Dot2::default()),
+ }.into())
));
named!(field_pat -> FieldPat, alt!(
@@ -1268,6 +1525,7 @@
pat: Box::new(pat),
is_shorthand: false,
attrs: Vec::new(),
+ colon_token: Some(tokens::Colon::default()),
})
)
|
@@ -1277,54 +1535,72 @@
mutability: mutability >>
ident: ident >>
({
- let mut pat = Pat::Ident(
- if mode.is_some() {
- BindingMode::ByRef(mutability)
+ let mut pat: Pat = PatIdent {
+ mode: if mode.is_some() {
+ BindingMode::ByRef(tokens::Ref::default(), mutability)
} else {
BindingMode::ByValue(mutability)
},
- ident.clone(),
- None,
- );
+ ident: ident.clone(),
+ subpat: None,
+ at_token: None,
+ }.into();
if boxed.is_some() {
- pat = Pat::Box(Box::new(pat));
+ pat = PatBox {
+ pat: Box::new(pat),
+ box_token: tokens::Box::default(),
+ }.into();
}
FieldPat {
ident: ident,
pat: Box::new(pat),
is_shorthand: true,
attrs: Vec::new(),
+ colon_token: None,
}
})
)
));
- named!(pat_path -> Pat, map!(qpath, |(qself, path)| Pat::Path(qself, path)));
+ named!(pat_path -> Pat, map!(qpath, |(qself, path)| {
+ PatPath { qself: qself, path: path }.into()
+ }));
- named!(pat_tuple -> Pat, map!(
- pat_tuple_helper,
- |(pats, dotdot)| Pat::Tuple(pats, dotdot)
- ));
-
- named!(pat_tuple_helper -> (Vec<Pat>, Option<usize>), do_parse!(
+ named!(pat_tuple -> PatTuple, do_parse!(
punct!("(") >>
- mut elems: separated_list!(punct!(","), pat) >>
- dotdot: option!(do_parse!(
- cond!(!elems.is_empty(), punct!(",")) >>
- punct!("..") >>
- rest: many0!(preceded!(punct!(","), pat)) >>
- cond!(!rest.is_empty(), option!(punct!(","))) >>
- (rest)
- )) >>
- cond!(!elems.is_empty() && dotdot.is_none(), option!(punct!(","))) >>
+ mut elems: terminated_list!(map!(punct!(","), |_| tokens::Comma::default()),
+ pat) >>
+ dotdot: map!(cond!(
+ elems.is_empty() || elems.trailing_delim(),
+ option!(do_parse!(
+ punct!("..") >>
+ trailing: option!(punct!(",")) >>
+ (trailing.is_some())
+ ))
+ ), |x: Option<_>| x.and_then(|x| x)) >>
+ rest: cond!(dotdot == Some(true),
+ terminated_list!(map!(punct!(","), |_| tokens::Comma::default()),
+ pat)) >>
punct!(")") >>
- (match dotdot {
- Some(rest) => {
- let pos = elems.len();
- elems.extend(rest);
- (elems, Some(pos))
- }
- None => (elems, None),
+ (PatTuple {
+ paren_token: tokens::Paren::default(),
+ dots_pos: dotdot.map(|_| elems.len()),
+ dot2_token: dotdot.map(|_| tokens::Dot2::default()),
+ comma_token: dotdot.and_then(|b| {
+ if b {
+ Some(tokens::Comma::default())
+ } else {
+ None
+ }
+ }),
+ pats: {
+ if let Some(rest) = rest {
+ for elem in rest.into_iter() {
+ elems.push(elem);
+ }
+ }
+ elems
+ },
})
));
@@ -1332,7 +1608,11 @@
punct!("&") >>
mutability: mutability >>
pat: pat >>
- (Pat::Ref(Box::new(pat), mutability))
+ (PatRef {
+ pat: Box::new(pat),
+ mutbl: mutability,
+ and_token: tokens::And::default(),
+ }.into())
));
named!(pat_lit -> Pat, do_parse!(
@@ -1340,7 +1620,9 @@
(if let ExprKind::Path(_) = lit.node {
return IResult::Error; // these need to be parsed by pat_path
} else {
- Pat::Lit(Box::new(lit))
+ PatLit {
+ expr: Box::new(lit),
+ }.into()
})
));
@@ -1348,7 +1630,11 @@
lo: pat_lit_expr >>
limits: range_limits >>
hi: pat_lit_expr >>
- (Pat::Range(Box::new(lo), Box::new(hi), limits))
+ (PatRange {
+ lo: Box::new(lo),
+ hi: Box::new(hi),
+ limits: limits,
+ }.into())
));
named!(pat_lit_expr -> Expr, do_parse!(
@@ -1360,7 +1646,7 @@
) >>
(if neg.is_some() {
ExprKind::Unary(ExprUnary {
- op: UnOp::Neg,
+ op: UnOp::Neg(tokens::Sub::default()),
expr: Box::new(v.into())
}).into()
} else {
@@ -1370,33 +1656,43 @@
named!(pat_slice -> Pat, do_parse!(
punct!("[") >>
- mut before: separated_list!(punct!(","), pat) >>
- after: option!(do_parse!(
- comma_before_dots: option!(cond_reduce!(!before.is_empty(), punct!(","))) >>
+ mut before: terminated_list!(map!(punct!(","), |_| tokens::Comma::default()),
+ pat) >>
+ middle: option!(do_parse!(
punct!("..") >>
- after: many0!(preceded!(punct!(","), pat)) >>
- cond!(!after.is_empty(), option!(punct!(","))) >>
- (comma_before_dots.is_some(), after)
+ trailing: option!(punct!(",")) >>
+ (trailing.is_some())
)) >>
- cond!(after.is_none(), option!(punct!(","))) >>
+ after: cond!(
+ match middle {
+ Some(trailing) => trailing,
+ _ => false,
+ },
+ terminated_list!(map!(punct!(","), |_| tokens::Comma::default()),
+ pat)
+ ) >>
punct!("]") >>
- (match after {
- None => Pat::Slice(before, None, Vec::new()),
- Some((true, after)) => {
- if before.is_empty() {
- return IResult::Error;
+ (PatSlice {
+ dot2_token: middle.as_ref().map(|_| tokens::Dot2::default()),
+ comma_token: {
+ let trailing = middle.unwrap_or(false);
+ if trailing {Some(tokens::Comma::default())} else {None}
+ },
+ bracket_token: tokens::Bracket::default(),
+ middle: middle.and_then(|_| {
+ if !before.is_empty() && !before.trailing_delim() {
+ Some(Box::new(before.pop().unwrap().into_item()))
+ } else {
+ None
}
- Pat::Slice(before, Some(Box::new(Pat::Wild)), after)
- }
- Some((false, after)) => {
- let rest = before.pop().unwrap_or(Pat::Wild);
- Pat::Slice(before, Some(Box::new(rest)), after)
- }
- })
+ }),
+ front: before,
+ back: after.unwrap_or_default(),
+ }.into())
));
named!(capture_by -> CaptureBy, alt!(
- keyword!("move") => { |_| CaptureBy::Value }
+ keyword!("move") => { |_| CaptureBy::Value(tokens::Move::default()) }
|
epsilon!() => { |_| CaptureBy::Ref }
));
@@ -1407,7 +1703,6 @@
#[cfg(feature = "printing")]
mod printing {
use super::*;
- use {FnArg, FunctionRetTy, Mutability, Ty, Unsafety, ArgCaptured};
use attr::FilterAttrs;
use quote::{Tokens, ToTokens};
@@ -1420,14 +1715,14 @@
impl ToTokens for ExprBox {
fn to_tokens(&self, tokens: &mut Tokens) {
- tokens.append("box");
+ self.box_token.to_tokens(tokens);
self.expr.to_tokens(tokens);
}
}
impl ToTokens for ExprInPlace {
fn to_tokens(&self, tokens: &mut Tokens) {
- tokens.append("in");
+ self.in_token.to_tokens(tokens);
self.place.to_tokens(tokens);
self.value.to_tokens(tokens);
}
@@ -1435,46 +1730,42 @@
impl ToTokens for ExprArray {
fn to_tokens(&self, tokens: &mut Tokens) {
- tokens.append("[");
- tokens.append_separated(&self.exprs, ",");
- tokens.append("]");
+ self.bracket_token.surround(tokens, |tokens| {
+ self.exprs.to_tokens(tokens);
+ })
}
}
impl ToTokens for ExprCall {
fn to_tokens(&self, tokens: &mut Tokens) {
self.func.to_tokens(tokens);
- tokens.append("(");
- tokens.append_separated(&self.args, ",");
- tokens.append(")");
+ self.paren_token.surround(tokens, |tokens| {
+ self.args.to_tokens(tokens);
+ })
}
}
impl ToTokens for ExprMethodCall {
fn to_tokens(&self, tokens: &mut Tokens) {
- self.args[0].to_tokens(tokens);
- tokens.append(".");
+ self.expr.to_tokens(tokens);
+ self.dot_token.to_tokens(tokens);
self.method.to_tokens(tokens);
- if !self.typarams.is_empty() {
- tokens.append("::");
- tokens.append("<");
- tokens.append_separated(&self.typarams, ",");
- tokens.append(">");
- }
- tokens.append("(");
- tokens.append_separated(&self.args[1..], ",");
- tokens.append(")");
+ self.colon2_token.to_tokens(tokens);
+ self.lt_token.to_tokens(tokens);
+ self.typarams.to_tokens(tokens);
+ self.gt_token.to_tokens(tokens);
+ self.paren_token.surround(tokens, |tokens| {
+ self.args.to_tokens(tokens);
+ });
}
}
impl ToTokens for ExprTup {
fn to_tokens(&self, tokens: &mut Tokens) {
- tokens.append("(");
- tokens.append_separated(&self.args, ",");
- if self.args.len() == 1 {
- tokens.append(",");
- }
- tokens.append(")");
+ self.paren_token.surround(tokens, |tokens| {
+ self.args.to_tokens(tokens);
+ self.lone_comma.to_tokens(tokens);
+ })
}
}
@@ -1496,7 +1787,7 @@
impl ToTokens for ExprCast {
fn to_tokens(&self, tokens: &mut Tokens) {
self.expr.to_tokens(tokens);
- tokens.append("as");
+ self.as_token.to_tokens(tokens);
self.ty.to_tokens(tokens);
}
}
@@ -1504,45 +1795,39 @@
impl ToTokens for ExprType {
fn to_tokens(&self, tokens: &mut Tokens) {
self.expr.to_tokens(tokens);
- tokens.append(":");
+ self.colon_token.to_tokens(tokens);
self.ty.to_tokens(tokens);
}
}
impl ToTokens for ExprIf {
fn to_tokens(&self, tokens: &mut Tokens) {
- tokens.append("if");
+ self.if_token.to_tokens(tokens);
self.cond.to_tokens(tokens);
self.if_true.to_tokens(tokens);
- if let Some(ref else_block) = self.if_false {
- tokens.append("else");
- else_block.to_tokens(tokens);
- }
+ self.else_token.to_tokens(tokens);
+ self.if_false.to_tokens(tokens);
}
}
impl ToTokens for ExprIfLet {
fn to_tokens(&self, tokens: &mut Tokens) {
- tokens.append("if");
- tokens.append("let");
+ self.if_token.to_tokens(tokens);
+ self.let_token.to_tokens(tokens);
self.pat.to_tokens(tokens);
- tokens.append("=");
+ self.eq_token.to_tokens(tokens);
self.expr.to_tokens(tokens);
self.if_true.to_tokens(tokens);
- if let Some(ref else_block) = self.if_false {
- tokens.append("else");
- else_block.to_tokens(tokens);
- }
+ self.else_token.to_tokens(tokens);
+ self.if_false.to_tokens(tokens);
}
}
impl ToTokens for ExprWhile {
fn to_tokens(&self, tokens: &mut Tokens) {
- if let Some(ref label) = self.label {
- label.to_tokens(tokens);
- tokens.append(":");
- }
- tokens.append("while");
+ self.label.to_tokens(tokens);
+ self.colon_token.to_tokens(tokens);
+ self.while_token.to_tokens(tokens);
self.cond.to_tokens(tokens);
self.body.to_tokens(tokens);
}
@@ -1550,14 +1835,12 @@
impl ToTokens for ExprWhileLet {
fn to_tokens(&self, tokens: &mut Tokens) {
- if let Some(ref label) = self.label {
- label.to_tokens(tokens);
- tokens.append(":");
- }
- tokens.append("while");
- tokens.append("let");
+ self.label.to_tokens(tokens);
+ self.colon_token.to_tokens(tokens);
+ self.while_token.to_tokens(tokens);
+ self.let_token.to_tokens(tokens);
self.pat.to_tokens(tokens);
- tokens.append("=");
+ self.eq_token.to_tokens(tokens);
self.expr.to_tokens(tokens);
self.body.to_tokens(tokens);
}
@@ -1565,13 +1848,11 @@
impl ToTokens for ExprForLoop {
fn to_tokens(&self, tokens: &mut Tokens) {
- if let Some(ref label) = self.label {
- label.to_tokens(tokens);
- tokens.append(":");
- }
- tokens.append("for");
+ self.label.to_tokens(tokens);
+ self.colon_token.to_tokens(tokens);
+ self.for_token.to_tokens(tokens);
self.pat.to_tokens(tokens);
- tokens.append("in");
+ self.in_token.to_tokens(tokens);
self.expr.to_tokens(tokens);
self.body.to_tokens(tokens);
}
@@ -1579,29 +1860,27 @@
impl ToTokens for ExprLoop {
fn to_tokens(&self, tokens: &mut Tokens) {
- if let Some(ref label) = self.label {
- label.to_tokens(tokens);
- tokens.append(":");
- }
- tokens.append("loop");
+ self.label.to_tokens(tokens);
+ self.colon_token.to_tokens(tokens);
+ self.loop_token.to_tokens(tokens);
self.body.to_tokens(tokens);
}
}
impl ToTokens for ExprMatch {
fn to_tokens(&self, tokens: &mut Tokens) {
- tokens.append("match");
+ self.match_token.to_tokens(tokens);
self.expr.to_tokens(tokens);
- tokens.append("{");
- tokens.append_all(&self.arms);
- tokens.append("}");
+ self.brace_token.surround(tokens, |tokens| {
+ tokens.append_all(&self.arms);
+ });
}
}
impl ToTokens for ExprCatch {
fn to_tokens(&self, tokens: &mut Tokens) {
- tokens.append("do");
- tokens.append("catch");
+ self.do_token.to_tokens(tokens);
+ self.catch_token.to_tokens(tokens);
self.block.to_tokens(tokens);
}
}
@@ -1609,26 +1888,18 @@
impl ToTokens for ExprClosure {
fn to_tokens(&self, tokens: &mut Tokens) {
self.capture.to_tokens(tokens);
- tokens.append("|");
- for (i, input) in self.decl.inputs.iter().enumerate() {
- if i > 0 {
- tokens.append(",");
- }
- match *input {
- FnArg::Captured(ArgCaptured { ref pat, ty: Ty::Infer(_) }) => {
+ self.or1_token.to_tokens(tokens);
+ for item in self.decl.inputs.iter() {
+ match **item.item() {
+ FnArg::Captured(ArgCaptured { ref pat, ty: Ty::Infer(_), .. }) => {
pat.to_tokens(tokens);
}
- _ => input.to_tokens(tokens),
+ _ => item.item().to_tokens(tokens),
}
+ item.delimiter().to_tokens(tokens);
}
- tokens.append("|");
- match self.decl.output {
- FunctionRetTy::Default => { /* nothing */ }
- FunctionRetTy::Ty(ref ty) => {
- tokens.append("->");
- ty.to_tokens(tokens);
- }
- }
+ self.or2_token.to_tokens(tokens);
+ self.decl.output.to_tokens(tokens);
self.body.to_tokens(tokens);
}
}
@@ -1643,7 +1914,7 @@
impl ToTokens for ExprAssign {
fn to_tokens(&self, tokens: &mut Tokens) {
self.left.to_tokens(tokens);
- tokens.append("=");
+ self.eq_token.to_tokens(tokens);
self.right.to_tokens(tokens);
}
}
@@ -1651,7 +1922,7 @@
impl ToTokens for ExprAssignOp {
fn to_tokens(&self, tokens: &mut Tokens) {
self.left.to_tokens(tokens);
- tokens.append(self.op.assign_op().unwrap());
+ self.op.to_tokens(tokens);
self.right.to_tokens(tokens);
}
}
@@ -1659,7 +1930,7 @@
impl ToTokens for ExprField {
fn to_tokens(&self, tokens: &mut Tokens) {
self.expr.to_tokens(tokens);
- tokens.append(".");
+ self.dot_token.to_tokens(tokens);
self.field.to_tokens(tokens);
}
}
@@ -1667,17 +1938,17 @@
impl ToTokens for ExprTupField {
fn to_tokens(&self, tokens: &mut Tokens) {
self.expr.to_tokens(tokens);
- tokens.append(".");
- tokens.append(&self.field.to_string());
+ self.dot_token.to_tokens(tokens);
+ self.field.to_tokens(tokens);
}
}
impl ToTokens for ExprIndex {
fn to_tokens(&self, tokens: &mut Tokens) {
self.expr.to_tokens(tokens);
- tokens.append("[");
- self.index.to_tokens(tokens);
- tokens.append("]");
+ self.bracket_token.surround(tokens, |tokens| {
+ self.index.to_tokens(tokens);
+ });
}
}
@@ -1691,35 +1962,13 @@
impl ToTokens for ExprPath {
fn to_tokens(&self, tokens: &mut Tokens) {
- let qself = match self.qself {
- Some(ref qself) => qself,
- None => return self.path.to_tokens(tokens),
- };
- tokens.append("<");
- qself.ty.to_tokens(tokens);
- if qself.position > 0 {
- tokens.append("as");
- for (i, segment) in self.path.segments
- .iter()
- .take(qself.position)
- .enumerate() {
- if i > 0 || self.path.global {
- tokens.append("::");
- }
- segment.to_tokens(tokens);
- }
- }
- tokens.append(">");
- for segment in self.path.segments.iter().skip(qself.position) {
- tokens.append("::");
- segment.to_tokens(tokens);
- }
+ ::PathTokens(&self.qself, &self.path).to_tokens(tokens)
}
}
impl ToTokens for ExprAddrOf {
fn to_tokens(&self, tokens: &mut Tokens) {
- tokens.append("&");
+ self.and_token.to_tokens(tokens);
self.mutbl.to_tokens(tokens);
self.expr.to_tokens(tokens);
}
@@ -1727,7 +1976,7 @@
impl ToTokens for ExprBreak {
fn to_tokens(&self, tokens: &mut Tokens) {
- tokens.append("break");
+ self.break_token.to_tokens(tokens);
self.label.to_tokens(tokens);
self.expr.to_tokens(tokens);
}
@@ -1735,14 +1984,14 @@
impl ToTokens for ExprContinue {
fn to_tokens(&self, tokens: &mut Tokens) {
- tokens.append("continue");
+ self.continue_token.to_tokens(tokens);
self.label.to_tokens(tokens);
}
}
impl ToTokens for ExprRet {
fn to_tokens(&self, tokens: &mut Tokens) {
- tokens.append("return");
+ self.return_token.to_tokens(tokens);
self.expr.to_tokens(tokens);
}
}
@@ -1750,41 +1999,36 @@
impl ToTokens for ExprStruct {
fn to_tokens(&self, tokens: &mut Tokens) {
self.path.to_tokens(tokens);
- tokens.append("{");
- tokens.append_separated(&self.fields, ",");
- if let Some(ref base) = self.rest {
- if !self.fields.is_empty() {
- tokens.append(",");
- }
- tokens.append("..");
- base.to_tokens(tokens);
- }
- tokens.append("}");
+ self.brace_token.surround(tokens, |tokens| {
+ self.fields.to_tokens(tokens);
+ self.dot2_token.to_tokens(tokens);
+ self.rest.to_tokens(tokens);
+ })
}
}
impl ToTokens for ExprRepeat {
fn to_tokens(&self, tokens: &mut Tokens) {
- tokens.append("[");
- self.expr.to_tokens(tokens);
- tokens.append(";");
- self.amt.to_tokens(tokens);
- tokens.append("]");
+ self.bracket_token.surround(tokens, |tokens| {
+ self.expr.to_tokens(tokens);
+ self.semi_token.to_tokens(tokens);
+ self.amt.to_tokens(tokens);
+ })
}
}
impl ToTokens for ExprParen {
fn to_tokens(&self, tokens: &mut Tokens) {
- tokens.append("(");
- self.expr.to_tokens(tokens);
- tokens.append(")");
+ self.paren_token.surround(tokens, |tokens| {
+ self.expr.to_tokens(tokens);
+ });
}
}
impl ToTokens for ExprTry {
fn to_tokens(&self, tokens: &mut Tokens) {
self.expr.to_tokens(tokens);
- tokens.append("?");
+ self.question_token.to_tokens(tokens);
}
}
@@ -1792,7 +2036,7 @@
fn to_tokens(&self, tokens: &mut Tokens) {
self.ident.to_tokens(tokens);
if !self.is_shorthand {
- tokens.append(":");
+ self.colon_token.to_tokens(tokens);
self.expr.to_tokens(tokens);
}
}
@@ -1800,157 +2044,118 @@
impl ToTokens for Arm {
fn to_tokens(&self, tokens: &mut Tokens) {
- for attr in &self.attrs {
- attr.to_tokens(tokens);
- }
- tokens.append_separated(&self.pats, "|");
- if let Some(ref guard) = self.guard {
- tokens.append("if");
- guard.to_tokens(tokens);
- }
- tokens.append("=>");
+ tokens.append_all(&self.attrs);
+ self.pats.to_tokens(tokens);
+ self.if_token.to_tokens(tokens);
+ self.guard.to_tokens(tokens);
+ self.rocket_token.to_tokens(tokens);
self.body.to_tokens(tokens);
- match self.body.node {
- ExprKind::Block(ExprBlock { unsafety: Unsafety::Normal, .. }) => {
- // no comma
- }
- _ => tokens.append(","),
- }
+ self.comma.to_tokens(tokens);
}
}
- impl ToTokens for Pat {
+ impl ToTokens for PatWild {
fn to_tokens(&self, tokens: &mut Tokens) {
- match *self {
- Pat::Wild => tokens.append("_"),
- Pat::Ident(ref mode, ref ident, ref subpat) => {
- mode.to_tokens(tokens);
- ident.to_tokens(tokens);
- if let Some(ref subpat) = *subpat {
- tokens.append("@");
- subpat.to_tokens(tokens);
+ self.underscore_token.to_tokens(tokens);
+ }
+ }
+
+ impl ToTokens for PatIdent {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ self.mode.to_tokens(tokens);
+ self.ident.to_tokens(tokens);
+ self.at_token.to_tokens(tokens);
+ self.subpat.to_tokens(tokens);
+ }
+ }
+
+ impl ToTokens for PatStruct {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ self.path.to_tokens(tokens);
+ self.brace_token.surround(tokens, |tokens| {
+ self.fields.to_tokens(tokens);
+ self.dot2_token.to_tokens(tokens);
+ });
+ }
+ }
+
+ impl ToTokens for PatTupleStruct {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ self.path.to_tokens(tokens);
+ self.pat.to_tokens(tokens);
+ }
+ }
+
+ impl ToTokens for PatPath {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ ::PathTokens(&self.qself, &self.path).to_tokens(tokens);
+ }
+ }
+
+ impl ToTokens for PatTuple {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ self.paren_token.surround(tokens, |tokens| {
+ for (i, token) in self.pats.iter().enumerate() {
+ if Some(i) == self.dots_pos {
+ self.dot2_token.to_tokens(tokens);
+ self.comma_token.to_tokens(tokens);
}
+ token.to_tokens(tokens);
}
- Pat::Struct(ref path, ref fields, dots) => {
- path.to_tokens(tokens);
- tokens.append("{");
- tokens.append_separated(fields, ",");
- if dots {
- if !fields.is_empty() {
- tokens.append(",");
- }
- tokens.append("..");
- }
- tokens.append("}");
+
+ if Some(self.pats.len()) == self.dots_pos {
+ self.dot2_token.to_tokens(tokens);
}
- Pat::TupleStruct(ref path, ref pats, dotpos) => {
- path.to_tokens(tokens);
- tokens.append("(");
- match dotpos {
- Some(pos) => {
- if pos > 0 {
- tokens.append_separated(&pats[..pos], ",");
- tokens.append(",");
- }
- tokens.append("..");
- if pos < pats.len() {
- tokens.append(",");
- tokens.append_separated(&pats[pos..], ",");
- }
- }
- None => tokens.append_separated(pats, ","),
- }
- tokens.append(")");
- }
- Pat::Path(None, ref path) => path.to_tokens(tokens),
- Pat::Path(Some(ref qself), ref path) => {
- tokens.append("<");
- qself.ty.to_tokens(tokens);
- if qself.position > 0 {
- tokens.append("as");
- for (i, segment) in path.segments
- .iter()
- .take(qself.position)
- .enumerate() {
- if i > 0 || path.global {
- tokens.append("::");
- }
- segment.to_tokens(tokens);
- }
- }
- tokens.append(">");
- for segment in path.segments.iter().skip(qself.position) {
- tokens.append("::");
- segment.to_tokens(tokens);
- }
- }
- Pat::Tuple(ref pats, dotpos) => {
- tokens.append("(");
- match dotpos {
- Some(pos) => {
- if pos > 0 {
- tokens.append_separated(&pats[..pos], ",");
- tokens.append(",");
- }
- tokens.append("..");
- if pos < pats.len() {
- tokens.append(",");
- tokens.append_separated(&pats[pos..], ",");
- }
- }
- None => {
- tokens.append_separated(pats, ",");
- if pats.len() == 1 {
- tokens.append(",");
- }
- }
- }
- tokens.append(")");
- }
- Pat::Box(ref inner) => {
- tokens.append("box");
- inner.to_tokens(tokens);
- }
- Pat::Ref(ref target, ref mutability) => {
- tokens.append("&");
- mutability.to_tokens(tokens);
- target.to_tokens(tokens);
- }
- Pat::Lit(ref lit) => lit.to_tokens(tokens),
- Pat::Range(ref lo, ref hi, ref limits) => {
- lo.to_tokens(tokens);
- limits.to_tokens(tokens);
- hi.to_tokens(tokens);
- }
- Pat::Slice(ref before, ref rest, ref after) => {
- tokens.append("[");
- tokens.append_separated(before, ",");
- if let Some(ref rest) = *rest {
- if !before.is_empty() {
- tokens.append(",");
- }
- match **rest {
- Pat::Wild => {}
- _ => rest.to_tokens(tokens),
- }
- tokens.append("..");
- if !after.is_empty() {
- tokens.append(",");
- }
- tokens.append_separated(after, ",");
- }
- tokens.append("]");
- }
- Pat::Mac(ref mac) => mac.to_tokens(tokens),
- }
+ });
+ }
+ }
+
+ impl ToTokens for PatBox {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ self.box_token.to_tokens(tokens);
+ self.pat.to_tokens(tokens);
+ }
+ }
+
+ impl ToTokens for PatRef {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ self.and_token.to_tokens(tokens);
+ self.mutbl.to_tokens(tokens);
+ self.pat.to_tokens(tokens);
+ }
+ }
+
+ impl ToTokens for PatLit {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ self.expr.to_tokens(tokens);
+ }
+ }
+
+ impl ToTokens for PatRange {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ self.lo.to_tokens(tokens);
+ self.limits.to_tokens(tokens);
+ self.hi.to_tokens(tokens);
+ }
+ }
+
+ impl ToTokens for PatSlice {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ self.bracket_token.surround(tokens, |tokens| {
+ self.front.to_tokens(tokens);
+ self.middle.to_tokens(tokens);
+ self.dot2_token.to_tokens(tokens);
+ self.comma_token.to_tokens(tokens);
+ self.back.to_tokens(tokens);
+ })
}
}
impl ToTokens for RangeLimits {
fn to_tokens(&self, tokens: &mut Tokens) {
match *self {
- RangeLimits::HalfOpen => tokens.append(".."),
- RangeLimits::Closed => tokens.append("..."),
+ RangeLimits::HalfOpen(ref t) => t.to_tokens(tokens),
+ RangeLimits::Closed(ref t) => t.to_tokens(tokens),
}
}
}
@@ -1959,7 +2164,7 @@
fn to_tokens(&self, tokens: &mut Tokens) {
if !self.is_shorthand {
self.ident.to_tokens(tokens);
- tokens.append(":");
+ self.colon_token.to_tokens(tokens);
}
self.pat.to_tokens(tokens);
}
@@ -1968,16 +2173,12 @@
impl ToTokens for BindingMode {
fn to_tokens(&self, tokens: &mut Tokens) {
match *self {
- BindingMode::ByRef(Mutability::Immutable) => {
- tokens.append("ref");
+ BindingMode::ByRef(ref t, ref m) => {
+ t.to_tokens(tokens);
+ m.to_tokens(tokens);
}
- BindingMode::ByRef(Mutability::Mutable) => {
- tokens.append("ref");
- tokens.append("mut");
- }
- BindingMode::ByValue(Mutability::Immutable) => {}
- BindingMode::ByValue(Mutability::Mutable) => {
- tokens.append("mut");
+ BindingMode::ByValue(ref m) => {
+ m.to_tokens(tokens);
}
}
}
@@ -1986,7 +2187,7 @@
impl ToTokens for CaptureBy {
fn to_tokens(&self, tokens: &mut Tokens) {
match *self {
- CaptureBy::Value => tokens.append("move"),
+ CaptureBy::Value(ref t) => t.to_tokens(tokens),
CaptureBy::Ref => {
// nothing
}
@@ -1996,9 +2197,9 @@
impl ToTokens for Block {
fn to_tokens(&self, tokens: &mut Tokens) {
- tokens.append("{");
- tokens.append_all(&self.stmts);
- tokens.append("}");
+ self.brace_token.surround(tokens, |tokens| {
+ tokens.append_all(&self.stmts);
+ });
}
}
@@ -2008,16 +2209,16 @@
Stmt::Local(ref local) => local.to_tokens(tokens),
Stmt::Item(ref item) => item.to_tokens(tokens),
Stmt::Expr(ref expr) => expr.to_tokens(tokens),
- Stmt::Semi(ref expr) => {
+ Stmt::Semi(ref expr, ref semi) => {
expr.to_tokens(tokens);
- tokens.append(";");
+ semi.to_tokens(tokens);
}
Stmt::Mac(ref mac) => {
let (ref mac, ref style, ref attrs) = **mac;
tokens.append_all(attrs.outer());
mac.to_tokens(tokens);
match *style {
- MacStmtStyle::Semicolon => tokens.append(";"),
+ MacStmtStyle::Semicolon(ref s) => s.to_tokens(tokens),
MacStmtStyle::Braces | MacStmtStyle::NoBraces => {
// no semicolon
}
@@ -2030,17 +2231,13 @@
impl ToTokens for Local {
fn to_tokens(&self, tokens: &mut Tokens) {
tokens.append_all(self.attrs.outer());
- tokens.append("let");
+ self.let_token.to_tokens(tokens);
self.pat.to_tokens(tokens);
- if let Some(ref ty) = self.ty {
- tokens.append(":");
- ty.to_tokens(tokens);
- }
- if let Some(ref init) = self.init {
- tokens.append("=");
- init.to_tokens(tokens);
- }
- tokens.append(";");
+ self.colon_token.to_tokens(tokens);
+ self.ty.to_tokens(tokens);
+ self.eq_token.to_tokens(tokens);
+ self.init.to_tokens(tokens);
+ self.semi_token.to_tokens(tokens);
}
}
}
diff --git a/src/fold.rs b/src/fold.rs
index 3a5c763..2f4ef1c 100644
--- a/src/fold.rs
+++ b/src/fold.rs
@@ -7,6 +7,8 @@
#[cfg(not(feature = "full"))]
use constant;
+use delimited::{Delimited, Element};
+
/// AST->AST fold.
///
/// Each method of the Folder trait is a hook to be potentially overridden. Each
@@ -174,6 +176,20 @@
}
}
+impl<T, D, U> LiftMut<T, U> for Delimited<T, D> {
+ type Output = Delimited<U, D>;
+ fn lift<F>(self, mut f: F) -> Self::Output
+ where F: FnMut(T) -> U
+ {
+ self.into_iter().map(|e| {
+ match e {
+ Element::Delimited(t, d) => Element::Delimited(f(t), d),
+ Element::End(t) => Element::End(f(t))
+ }
+ }).collect()
+ }
+}
+
pub fn noop_fold_ident<F: ?Sized + Folder>(_: &mut F, _ident: Ident) -> Ident {
_ident
}
@@ -191,8 +207,18 @@
attrs: attrs.lift(|a| folder.fold_attribute(a)),
generics: folder.fold_generics(generics),
body: match body {
- Enum(variants) => Enum(variants.lift(move |v| folder.fold_variant(v))),
- Struct(variant_data) => Struct(folder.fold_variant_data(variant_data)),
+ Enum(data) => {
+ Enum(BodyEnum {
+ variants: data.variants.lift(move |v| folder.fold_variant(v)),
+ ..data
+ })
+ }
+ Struct(data) => {
+ Struct(BodyStruct {
+ data: folder.fold_variant_data(data.data),
+ ..data
+ })
+ }
},
}
}
@@ -202,136 +228,151 @@
use Ty::*;
match ty {
- Slice(TySlice { ty }) => {
+ Slice(t) => {
Slice(TySlice {
- ty: ty.lift(|v| folder.fold_ty(v)),
+ ty: t.ty.lift(|v| folder.fold_ty(v)),
+ ..t
})
}
- Paren(TyParen { ty }) => {
+ Paren(t) => {
Paren(TyParen {
- ty: ty.lift(|v| folder.fold_ty(v)),
+ ty: t.ty.lift(|v| folder.fold_ty(v)),
+ ..t
})
}
- Ptr(TyPtr { ty }) => {
- let ty = *ty;
+ Ptr(t) => {
+ let ty = *t.ty;
let MutTy { ty, mutability } = ty;
Ptr(TyPtr {
ty: Box::new(MutTy {
ty: folder.fold_ty(ty),
mutability: mutability,
}),
+ ..t
})
}
- Rptr(TyRptr { lifetime, ty }) => {
- let ty = *ty;
+ Rptr(t) => {
+ let ty = *t.ty;
let MutTy { ty, mutability } = ty;
Rptr(TyRptr {
- lifetime: lifetime.map(|l| folder.fold_lifetime(l)),
+ lifetime: t.lifetime.map(|l| folder.fold_lifetime(l)),
ty: Box::new(MutTy {
ty: folder.fold_ty(ty),
mutability: mutability,
}),
+ ..t
})
}
Never(t) => Never(t),
Infer(t) => Infer(t),
- Tup(TyTup { tys }) => {
+ Tup(t) => {
Tup(TyTup {
- tys: tys.lift(|x| folder.fold_ty(x)),
+ tys: t.tys.lift(|x| folder.fold_ty(x)),
+ ..t
})
}
- BareFn(TyBareFn { ty }) => {
- let ty = *ty;
- let BareFnTy { unsafety, abi, lifetimes, inputs, output, variadic } = ty;
+ BareFn(t) => {
+ let ty = *t.ty;
BareFn(TyBareFn {
ty: Box::new(BareFnTy {
- unsafety: unsafety,
- abi: abi,
- lifetimes: lifetimes.lift(|l| folder.fold_lifetime_def(l)),
- inputs: inputs.lift(|v| {
+ lifetimes: ty.lifetimes.map(|l| {
+ noop_fold_bound_lifetimes(folder, l)
+ }),
+ inputs: ty.inputs.lift(|v| {
BareFnArg {
- name: v.name.map(|n| folder.fold_ident(n)),
+ name: v.name.map(|n| (folder.fold_ident(n.0), n.1)),
ty: folder.fold_ty(v.ty),
}
}),
- output: folder.fold_fn_ret_ty(output),
- variadic: variadic,
+ output: folder.fold_fn_ret_ty(ty.output),
+ ..ty
}),
})
}
- Path(TyPath { qself, path }) => {
+ Path(t) => {
Path(TyPath {
- qself: qself.map(|v| noop_fold_qself(folder, v)),
- path: folder.fold_path(path),
+ qself: t.qself.map(|v| noop_fold_qself(folder, v)),
+ path: folder.fold_path(t.path),
})
}
- Array(TyArray { ty, amt }) => {
+ Array(t) => {
Array(TyArray {
- ty: ty.lift(|v| folder.fold_ty(v)),
- amt: folder.fold_const_expr(amt),
+ ty: t.ty.lift(|v| folder.fold_ty(v)),
+ amt: folder.fold_const_expr(t.amt),
+ ..t
})
}
- TraitObject(TyTraitObject { bounds }) => {
+ TraitObject(t) => {
TraitObject(TyTraitObject {
- bounds: bounds.lift(|v| folder.fold_ty_param_bound(v)),
+ bounds: t.bounds.lift(|v| folder.fold_ty_param_bound(v)),
})
}
- ImplTrait(TyImplTrait { bounds }) => {
+ ImplTrait(t) => {
ImplTrait(TyImplTrait {
- bounds: bounds.lift(|v| folder.fold_ty_param_bound(v)),
+ bounds: t.bounds.lift(|v| folder.fold_ty_param_bound(v)),
+ ..t
})
}
Mac(mac) => Mac(folder.fold_mac(mac)),
}
}
-fn noop_fold_qself<F: ?Sized + Folder>(folder: &mut F, QSelf { ty, position }: QSelf) -> QSelf {
+#[cfg_attr(feature = "cargo-clippy", allow(needless_pass_by_value))] // clippy lies
+fn noop_fold_qself<F: ?Sized + Folder>(folder: &mut F, qself: QSelf) -> QSelf {
QSelf {
- ty: Box::new(folder.fold_ty(*(ty))),
- position: position,
+ ty: Box::new(folder.fold_ty(*(qself.ty))),
+ ..qself
}
}
pub fn noop_fold_generics<F: ?Sized + Folder>(folder: &mut F,
- Generics { lifetimes, ty_params, where_clause }: Generics)
+ generics: Generics)
-> Generics{
use WherePredicate::*;
Generics {
- lifetimes: lifetimes.lift(|l| folder.fold_lifetime_def(l)),
- ty_params: ty_params.lift(|ty| {
+ lifetimes: generics.lifetimes.lift(|l| folder.fold_lifetime_def(l)),
+ ty_params: generics.ty_params.lift(|ty| {
TyParam {
attrs: ty.attrs.lift(|a| folder.fold_attribute(a)),
ident: folder.fold_ident(ty.ident),
bounds: ty.bounds.lift(|ty_pb| folder.fold_ty_param_bound(ty_pb)),
default: ty.default.map(|v| folder.fold_ty(v)),
+ ..ty
}
}),
where_clause: WhereClause {
- predicates: where_clause.predicates.lift(|p| match p {
- BoundPredicate(bound_predicate) => {
+ predicates: generics.where_clause.predicates.lift(|p| {
+ match p {
+ BoundPredicate(bound_predicate) => {
BoundPredicate(WhereBoundPredicate {
bound_lifetimes: bound_predicate.bound_lifetimes
- .lift(|l| folder.fold_lifetime_def(l)),
+ .map(|l| noop_fold_bound_lifetimes(folder, l)),
bounded_ty: folder.fold_ty(bound_predicate.bounded_ty),
bounds: bound_predicate.bounds
.lift(|ty_pb| folder.fold_ty_param_bound(ty_pb)),
+ ..bound_predicate
})
}
- RegionPredicate(region_predicate) => {
+ RegionPredicate(region_predicate) => {
RegionPredicate(WhereRegionPredicate {
lifetime: folder.fold_lifetime(region_predicate.lifetime),
bounds: region_predicate.bounds
.lift(|b| folder.fold_lifetime(b)),
+ ..region_predicate
})
}
- EqPredicate(eq_predicate) => {
+ EqPredicate(eq_predicate) => {
EqPredicate(WhereEqPredicate {
lhs_ty: folder.fold_ty(eq_predicate.lhs_ty),
rhs_ty: folder.fold_ty(eq_predicate.rhs_ty),
+ ..eq_predicate
})
}
- }),
+ }
+ }),
+ ..generics.where_clause
},
+ ..generics
}
}
@@ -349,7 +390,9 @@
trait_ref: PolyTraitRef)
-> PolyTraitRef {
PolyTraitRef {
- bound_lifetimes: trait_ref.bound_lifetimes.lift(|bl| folder.fold_lifetime_def(bl)),
+ bound_lifetimes: trait_ref.bound_lifetimes.map(|bl| {
+ noop_fold_bound_lifetimes(folder, bl)
+ }),
trait_ref: folder.fold_path(trait_ref.trait_ref),
}
}
@@ -359,8 +402,8 @@
-> VariantData {
use VariantData::*;
match data {
- Struct(fields) => Struct(fields.lift(|f| folder.fold_field(f))),
- Tuple(fields) => Tuple(fields.lift(|f| folder.fold_field(f))),
+ Struct(fields, t) => Struct(fields.lift(|f| folder.fold_field(f)), t),
+ Tuple(fields, t) => Tuple(fields.lift(|f| folder.fold_field(f)), t),
Unit => Unit,
}
}
@@ -371,17 +414,20 @@
vis: noop_fold_vis(folder, field.vis),
attrs: field.attrs.lift(|a| folder.fold_attribute(a)),
ty: folder.fold_ty(field.ty),
+ ..field
}
}
pub fn noop_fold_variant<F: ?Sized + Folder>(folder: &mut F,
- Variant { ident, attrs, data, discriminant }: Variant)
--> Variant{
+ variant: Variant)
+ -> Variant
+{
Variant {
- ident: folder.fold_ident(ident),
- attrs: attrs.lift(|v| folder.fold_attribute(v)),
- data: folder.fold_variant_data(data),
- discriminant: discriminant.map(|ce| folder.fold_const_expr(ce)),
+ ident: folder.fold_ident(variant.ident),
+ attrs: variant.attrs.lift(|v| folder.fold_attribute(v)),
+ data: folder.fold_variant_data(variant.data),
+ discriminant: variant.discriminant.map(|ce| folder.fold_const_expr(ce)),
+ ..variant
}
}
@@ -389,29 +435,41 @@
Lifetime { ident: folder.fold_ident(_lifetime.ident) }
}
-pub fn noop_fold_lifetime_def<F: ?Sized + Folder>(folder: &mut F,
- LifetimeDef { attrs, lifetime, bounds }: LifetimeDef)
--> LifetimeDef{
- LifetimeDef {
- attrs: attrs.lift(|x| folder.fold_attribute(x)),
- lifetime: folder.fold_lifetime(lifetime),
- bounds: bounds.lift(|l| folder.fold_lifetime(l)),
+pub fn noop_fold_bound_lifetimes<F: ?Sized + Folder>(folder: &mut F,
+ b: BoundLifetimes)
+ -> BoundLifetimes
+{
+ BoundLifetimes {
+ lifetimes: b.lifetimes.lift(|l| folder.fold_lifetime_def(l)),
+ ..b
}
}
-pub fn noop_fold_path<F: ?Sized + Folder>(folder: &mut F, Path { global, segments }: Path) -> Path {
+pub fn noop_fold_lifetime_def<F: ?Sized + Folder>(folder: &mut F,
+ def: LifetimeDef)
+ -> LifetimeDef
+{
+ LifetimeDef {
+ attrs: def.attrs.lift(|x| folder.fold_attribute(x)),
+ lifetime: folder.fold_lifetime(def.lifetime),
+ bounds: def.bounds.lift(|l| folder.fold_lifetime(l)),
+ ..def
+ }
+}
+
+pub fn noop_fold_path<F: ?Sized + Folder>(folder: &mut F, path: Path) -> Path {
Path {
- global: global,
- segments: segments.lift(|s| folder.fold_path_segment(s)),
+ segments: path.segments.lift(|s| folder.fold_path_segment(s)),
+ ..path
}
}
pub fn noop_fold_path_segment<F: ?Sized + Folder>(folder: &mut F,
- PathSegment { ident, parameters }: PathSegment)
+ seg: PathSegment)
-> PathSegment {
PathSegment {
- ident: folder.fold_ident(ident),
- parameters: folder.fold_path_parameters(parameters),
+ ident: folder.fold_ident(seg.ident),
+ parameters: folder.fold_path_parameters(seg.parameters),
}
}
@@ -421,37 +479,36 @@
use PathParameters::*;
match path_parameters {
AngleBracketed(d) => {
- let AngleBracketedParameterData { lifetimes, types, bindings } = d;
AngleBracketed(AngleBracketedParameterData {
- lifetimes: lifetimes.into_iter()
- .map(|l| folder.fold_lifetime(l))
- .collect(),
- types: types.lift(|ty| folder.fold_ty(ty)),
- bindings: bindings.lift(|tb| folder.fold_assoc_type_binding(tb)),
- })
+ lifetimes: d.lifetimes.lift(|l| folder.fold_lifetime(l)),
+ types: d.types.lift(|ty| folder.fold_ty(ty)),
+ bindings: d.bindings.lift(|tb| folder.fold_assoc_type_binding(tb)),
+ ..d
+ })
}
Parenthesized(d) => {
- let ParenthesizedParameterData { inputs, output } = d;
Parenthesized(ParenthesizedParameterData {
- inputs: inputs.lift(|i| folder.fold_ty(i)),
- output: output.map(|v| folder.fold_ty(v)),
- })
+ inputs: d.inputs.lift(|i| folder.fold_ty(i)),
+ output: folder.fold_fn_ret_ty(d.output),
+ ..d
+ })
}
}
}
pub fn noop_fold_assoc_type_binding<F: ?Sized + Folder>(folder: &mut F,
- TypeBinding { ident, ty }: TypeBinding)
- -> TypeBinding {
+ binding: TypeBinding)
+ -> TypeBinding
+{
TypeBinding {
- ident: folder.fold_ident(ident),
- ty: folder.fold_ty(ty),
+ ident: folder.fold_ident(binding.ident),
+ ty: folder.fold_ty(binding.ty),
+ ..binding
}
-
}
-pub fn noop_fold_attribute<F: ?Sized + Folder>(_: &mut F, _attr: Attribute) -> Attribute {
- _attr
+pub fn noop_fold_attribute<F: ?Sized + Folder>(_: &mut F, attr: Attribute) -> Attribute {
+ attr
}
pub fn noop_fold_fn_ret_ty<F: ?Sized + Folder>(folder: &mut F,
@@ -460,7 +517,7 @@
use FunctionRetTy::*;
match ret_ty {
Default => Default,
- Ty(ty) => Ty(folder.fold_ty(ty)),
+ Ty(ty, t) => Ty(folder.fold_ty(ty), t),
}
}
@@ -469,42 +526,46 @@
use constant::ConstExpr::*;
match expr {
- Call(ConstCall { func, args }) => {
+ Call(c) => {
Call(ConstCall {
- func: func.lift(|e| folder.fold_const_expr(e)),
- args: args.lift(|v| folder.fold_const_expr(v)),
+ func: c.func.lift(|e| folder.fold_const_expr(e)),
+ args: c.args.lift(|v| folder.fold_const_expr(v)),
+ ..c
})
}
- Binary(ConstBinary { op, left, right }) => {
+ Binary(c) => {
Binary(ConstBinary {
- op: op,
- left: left.lift(|e| folder.fold_const_expr(e)),
- right: right.lift(|e| folder.fold_const_expr(e)),
+ left: c.left.lift(|e| folder.fold_const_expr(e)),
+ right: c.right.lift(|e| folder.fold_const_expr(e)),
+ ..c
})
}
- Unary(ConstUnary { op, expr }) => {
+ Unary(c) => {
Unary(ConstUnary {
- op: op,
- expr: expr.lift(|e| folder.fold_const_expr(e)),
+ expr: c.expr.lift(|e| folder.fold_const_expr(e)),
+ ..c
})
}
Lit(l) => Lit(folder.fold_lit(l)),
- Cast(ConstCast { expr, ty }) => {
+ Cast(c) => {
Cast(ConstCast {
- expr: expr.lift(|e| folder.fold_const_expr(e)),
- ty: ty.lift(|v| folder.fold_ty(v)),
+ expr: c.expr.lift(|e| folder.fold_const_expr(e)),
+ ty: c.ty.lift(|v| folder.fold_ty(v)),
+ ..c
})
}
Path(p) => Path(folder.fold_path(p)),
- Index(ConstIndex { expr, index }) => {
+ Index(c) => {
Index(ConstIndex {
- expr: expr.lift(|e| folder.fold_const_expr(e)),
- index: index.lift(|e| folder.fold_const_expr(e)),
+ expr: c.expr.lift(|e| folder.fold_const_expr(e)),
+ index: c.index.lift(|e| folder.fold_const_expr(e)),
+ ..c
})
}
- Paren(ConstParen { expr }) => {
+ Paren(c) => {
Paren(ConstParen {
- expr: expr.lift(|e| folder.fold_const_expr(e)),
+ expr: c.expr.lift(|e| folder.fold_const_expr(e)),
+ ..c
})
}
Other(e) => Other(noop_fold_other_const_expr(folder, e)),
@@ -528,57 +589,74 @@
}
pub fn noop_fold_tt<F: ?Sized + Folder>(folder: &mut F, tt: TokenTree) -> TokenTree {
- use TokenTree::*;
- use Token::*;
- match tt {
- Token(token) => {
- Token(match token {
- Literal(lit) => Literal(folder.fold_lit(lit)),
- Ident(ident) => Ident(folder.fold_ident(ident)),
- Lifetime(ident) => Lifetime(folder.fold_ident(ident)),
- x => x,
- })
+ use proc_macro2::{TokenKind, TokenTree as TokenTree2};
+ match tt.0.kind {
+ TokenKind::Word(sym) => {
+ let sym = folder.fold_ident(Ident::new(sym, Span(tt.0.span)));
+ TokenTree(TokenTree2 {
+ span: sym.span.0,
+ kind: TokenKind::Word(sym.sym),
+ })
}
- Delimited(super::Delimited { delim, tts }) => {
- Delimited(super::Delimited {
- delim: delim,
- tts: tts.lift(|v| noop_fold_tt(folder, v)),
- })
+ TokenKind::Op(..) => tt,
+ TokenKind::Literal(lit) => {
+ folder.fold_lit(Lit {
+ value: LitKind::Other(lit),
+ span: Span(tt.0.span),
+ }).into_token_tree()
+ }
+ TokenKind::Sequence(delim, stream) => {
+ let stream = stream.into_iter().map(|tt| {
+ noop_fold_tt(folder, TokenTree(tt)).0
+ }).collect();
+ TokenTree(TokenTree2 {
+ span: tt.0.span,
+ kind: TokenKind::Sequence(delim, stream),
+ })
}
}
}
-pub fn noop_fold_mac<F: ?Sized + Folder>(folder: &mut F, Mac { path, tts }: Mac) -> Mac {
+pub fn noop_fold_mac<F: ?Sized + Folder>(folder: &mut F, mac: Mac) -> Mac {
Mac {
- path: folder.fold_path(path),
- tts: tts.lift(|tt| noop_fold_tt(folder, tt)),
+ path: folder.fold_path(mac.path),
+ tokens: mac.tokens.lift(|tt| noop_fold_tt(folder, tt)),
+ ..mac
}
}
#[cfg(feature = "full")]
pub fn noop_fold_crate<F: ?Sized + Folder>(folder: &mut F,
- Crate { shebang, attrs, items }: Crate)
+ krate: Crate)
-> Crate {
Crate {
- shebang: shebang,
- attrs: attrs.lift(|a| folder.fold_attribute(a)),
- items: items.lift(|i| folder.fold_item(i)),
+ attrs: krate.attrs.lift(|a| folder.fold_attribute(a)),
+ items: krate.items.lift(|i| folder.fold_item(i)),
+ ..krate
}
}
#[cfg(feature = "full")]
pub fn noop_fold_block<F: ?Sized + Folder>(folder: &mut F, block: Block) -> Block {
- Block { stmts: block.stmts.lift(|s| folder.fold_stmt(s)) }
+ Block {
+ stmts: block.stmts.lift(|s| folder.fold_stmt(s)),
+ ..block
+ }
}
fn noop_fold_vis<F: ?Sized + Folder>(folder: &mut F, vis: Visibility) -> Visibility {
use Visibility::*;
match vis {
- Crate => Crate,
- Inherited => Inherited,
- Public => Public,
- Restricted(path) => Restricted(path.lift(|p| folder.fold_path(p))),
+ Crate(t) => Crate(t),
+ Inherited(i) => Inherited(i),
+ Public(p) => Public(p),
+ Restricted(data) => {
+ Restricted(VisRestricted {
+ path: data.path.lift(|p| folder.fold_path(p)),
+ ..data
+ })
+ }
}
}
@@ -593,105 +671,105 @@
vis: noop_fold_vis(folder, vis),
attrs: attrs.lift(|a| folder.fold_attribute(a)),
node: match node {
- ExternCrate(ItemExternCrate { original }) => {
+ ExternCrate(i) => {
ExternCrate(ItemExternCrate {
- original: original.map(|i| folder.fold_ident(i)),
+ original: i.original.map(|i| folder.fold_ident(i)),
+ ..i
})
}
- Use(ItemUse { path }) => {
+ Use(i) => {
Use(ItemUse {
- path: Box::new(folder.fold_view_path(*path)),
+ path: Box::new(folder.fold_view_path(*i.path)),
+ ..i
})
}
- Static(ItemStatic { ty, mutbl, expr }) => {
+ Static(i) => {
Static(ItemStatic {
- ty: Box::new(folder.fold_ty(*ty)),
- mutbl: mutbl,
- expr: expr.lift(|e| folder.fold_expr(e)),
+ ty: Box::new(folder.fold_ty(*i.ty)),
+ mutbl: i.mutbl,
+ expr: i.expr.lift(|e| folder.fold_expr(e)),
+ ..i
})
}
- Const(ItemConst { ty, expr }) => {
+ Const(i) => {
Const(ItemConst {
- ty: ty.lift(|ty| folder.fold_ty(ty)),
- expr: expr.lift(|e| folder.fold_expr(e)),
+ ty: i.ty.lift(|ty| folder.fold_ty(ty)),
+ expr: i.expr.lift(|e| folder.fold_expr(e)),
+ ..i
})
}
- Fn(ItemFn { decl, unsafety, constness, abi, generics, block }) => {
+ Fn(i) => {
Fn(ItemFn {
- decl: decl.lift(|v| folder.fold_fn_decl(v)),
- unsafety: unsafety,
- constness: constness,
- abi: abi,
- generics: folder.fold_generics(generics),
- block: block.lift(|v| folder.fold_block(v)),
+ decl: i.decl.lift(|v| folder.fold_fn_decl(v)),
+ block: i.block.lift(|v| folder.fold_block(v)),
+ ..i
})
}
- Mod(ItemMod { items }) => {
+ Mod(i) => {
Mod(ItemMod {
- items: items.map(|items| items.lift(|i| folder.fold_item(i))),
+ items: i.items.map(|items| {
+ (items.0.lift(|i| folder.fold_item(i)), items.1)
+ }),
+ ..i
})
}
- ForeignMod(ItemForeignMod { abi, items }) => {
+ ForeignMod(i) => {
ForeignMod(ItemForeignMod {
- abi: abi,
- items: items.lift(|foreign_item| {
+ items: i.items.lift(|foreign_item| {
folder.fold_foreign_item(foreign_item)
}),
+ ..i
})
}
- Ty(ItemTy { ty, generics }) => {
+ Ty(i) => {
Ty(ItemTy {
- ty: ty.lift(|ty| folder.fold_ty(ty)),
- generics: folder.fold_generics(generics),
+ ty: i.ty.lift(|ty| folder.fold_ty(ty)),
+ generics: folder.fold_generics(i.generics),
+ ..i
})
}
- Enum(ItemEnum { variants, generics }) => {
+ Enum(i) => {
Enum(ItemEnum {
- variants: variants.lift(|v| folder.fold_variant(v)),
- generics: folder.fold_generics(generics),
+ variants: i.variants.lift(|v| folder.fold_variant(v)),
+ generics: folder.fold_generics(i.generics),
+ ..i
})
}
- Struct(ItemStruct { data, generics }) => {
+ Struct(i) => {
Struct(ItemStruct {
- data: folder.fold_variant_data(data),
- generics: folder.fold_generics(generics),
+ data: folder.fold_variant_data(i.data),
+ generics: folder.fold_generics(i.generics),
+ ..i
})
}
- Union(ItemUnion { data, generics }) => {
+ Union(i) => {
Union(ItemUnion {
- data: folder.fold_variant_data(data),
- generics: folder.fold_generics(generics),
+ data: folder.fold_variant_data(i.data),
+ generics: folder.fold_generics(i.generics),
+ ..i
})
}
- Trait(ItemTrait { unsafety, generics, supertraits, items }) => {
+ Trait(i) => {
Trait(ItemTrait {
- unsafety: unsafety,
- generics: folder.fold_generics(generics),
- supertraits: supertraits.lift(|typb| folder.fold_ty_param_bound(typb)),
- items: items.lift(|ti| folder.fold_trait_item(ti)),
+ generics: folder.fold_generics(i.generics),
+ supertraits: i.supertraits.lift(|typb| folder.fold_ty_param_bound(typb)),
+ items: i.items.lift(|ti| folder.fold_trait_item(ti)),
+ ..i
})
}
- DefaultImpl(ItemDefaultImpl { unsafety, path }) => {
+ DefaultImpl(i) => {
DefaultImpl(ItemDefaultImpl {
- unsafety: unsafety,
- path: folder.fold_path(path),
+ path: folder.fold_path(i.path),
+ ..i
})
}
- Impl(ItemImpl {
- unsafety,
- polarity,
- generics,
- trait_,
- self_ty,
- items,
- }) => {
+ Impl(i) => {
Impl(ItemImpl {
- unsafety: unsafety,
- polarity: polarity,
- generics: folder.fold_generics(generics),
- trait_: trait_.map(|p| folder.fold_path(p)),
- self_ty: self_ty.lift(|ty| folder.fold_ty(ty)),
- items: items.lift(|i| folder.fold_impl_item(i)),
+ generics: folder.fold_generics(i.generics),
+ trait_: i.trait_.map(|p| folder.fold_path(p)),
+ self_ty: i.self_ty.lift(|ty| folder.fold_ty(ty)),
+ items: i.items.lift(|i| folder.fold_impl_item(i)),
+ ..i
})
}
Mac(mac) => Mac(folder.fold_mac(mac)),
@@ -706,229 +784,264 @@
Expr {
node: match node {
- Box(ExprBox { expr }) => {
- Box(ExprBox { expr: expr.lift(|e| folder.fold_expr(e)) })
+ Box(e) => {
+ Box(ExprBox {
+ expr: e.expr.lift(|e| folder.fold_expr(e)),
+ ..e
+ })
}
- InPlace(ExprInPlace { place, value }) => {
+ InPlace(e) => {
InPlace(ExprInPlace {
- place: place.lift(|e| folder.fold_expr(e)),
- value: value.lift(|e| folder.fold_expr(e)),
+ place: e.place.lift(|e| folder.fold_expr(e)),
+ value: e.value.lift(|e| folder.fold_expr(e)),
+ ..e
})
}
- Array(ExprArray { exprs }) => {
+ Array(e) => {
Array(ExprArray {
- exprs: exprs.lift(|e| folder.fold_expr(e)),
+ exprs: e.exprs.lift(|e| folder.fold_expr(e)),
+ ..e
})
}
- Call(ExprCall { func, args }) => {
+ Call(e) => {
Call(ExprCall {
- func: func.lift(|e| folder.fold_expr(e)),
- args: args.lift(|e| folder.fold_expr(e)),
+ func: e.func.lift(|e| folder.fold_expr(e)),
+ args: e.args.lift(|e| folder.fold_expr(e)),
+ ..e
})
}
- MethodCall(ExprMethodCall { method, typarams, args }) => {
+ MethodCall(e) => {
MethodCall(ExprMethodCall {
- method: folder.fold_ident(method),
- typarams: typarams.lift(|t| folder.fold_ty(t)),
- args: args.lift(|e| folder.fold_expr(e)),
+ method: folder.fold_ident(e.method),
+ typarams: e.typarams.lift(|t| folder.fold_ty(t)),
+ args: e.args.lift(|e| folder.fold_expr(e)),
+ ..e
})
}
- Tup(ExprTup { args }) => {
+ Tup(e) => {
Tup(ExprTup {
- args: args.lift(|e| folder.fold_expr(e)),
+ args: e.args.lift(|e| folder.fold_expr(e)),
+ ..e
})
}
- Binary(ExprBinary { op, left, right }) => {
+ Binary(e) => {
Binary(ExprBinary {
- op: op,
- left: left.lift(|e| folder.fold_expr(e)),
- right: right.lift(|e| folder.fold_expr(e)),
+ left: e.left.lift(|e| folder.fold_expr(e)),
+ right: e.right.lift(|e| folder.fold_expr(e)),
+ ..e
})
}
- Unary(ExprUnary { op, expr }) => {
+ Unary(e) => {
Unary(ExprUnary {
- op: op,
- expr: expr.lift(|e| folder.fold_expr(e)),
+ expr: e.expr.lift(|e| folder.fold_expr(e)),
+ ..e
})
}
Lit(lit) => Lit(folder.fold_lit(lit)),
- Cast(ExprCast { expr, ty }) => {
+ Cast(e) => {
Cast(ExprCast {
- expr: expr.lift(|e| folder.fold_expr(e)),
- ty: ty.lift(|t| folder.fold_ty(t)),
+ expr: e.expr.lift(|e| folder.fold_expr(e)),
+ ty: e.ty.lift(|t| folder.fold_ty(t)),
+ ..e
})
}
- Type(ExprType { expr, ty }) => {
+ Type(e) => {
Type(ExprType {
- expr: expr.lift(|e| folder.fold_expr(e)),
- ty: ty.lift(|t| folder.fold_ty(t)),
+ expr: e.expr.lift(|e| folder.fold_expr(e)),
+ ty: e.ty.lift(|t| folder.fold_ty(t)),
+ ..e
})
}
- If(ExprIf { cond, if_true, if_false }) => {
+ If(e) => {
If(ExprIf {
- cond: cond.lift(|e| folder.fold_expr(e)),
- if_true: folder.fold_block(if_true),
- if_false: if_false.map(|v| v.lift(|e| folder.fold_expr(e))),
+ cond: e.cond.lift(|e| folder.fold_expr(e)),
+ if_true: folder.fold_block(e.if_true),
+ if_false: e.if_false.map(|v| v.lift(|e| folder.fold_expr(e))),
+ ..e
})
}
- IfLet(ExprIfLet { pat, expr, if_true, if_false }) => {
+ IfLet(e) => {
IfLet(ExprIfLet {
- pat: pat.lift(|p| folder.fold_pat(p)),
- expr: expr.lift(|e| folder.fold_expr(e)),
- if_true: folder.fold_block(if_true),
- if_false: if_false.map(|v| v.lift(|e| folder.fold_expr(e))),
+ pat: e.pat.lift(|p| folder.fold_pat(p)),
+ expr: e.expr.lift(|e| folder.fold_expr(e)),
+ if_true: folder.fold_block(e.if_true),
+ if_false: e.if_false.map(|v| v.lift(|e| folder.fold_expr(e))),
+ ..e
})
}
- While(ExprWhile { cond, body, label }) => {
+ While(e) => {
While(ExprWhile {
- cond: cond.lift(|e| folder.fold_expr(e)),
- body: folder.fold_block(body),
- label: label.map(|i| folder.fold_ident(i)),
+ cond: e.cond.lift(|e| folder.fold_expr(e)),
+ body: folder.fold_block(e.body),
+ label: e.label.map(|i| folder.fold_ident(i)),
+ ..e
})
}
- WhileLet(ExprWhileLet { pat, expr, body, label }) => {
+ WhileLet(e) => {
WhileLet(ExprWhileLet {
- pat: pat.lift(|p| folder.fold_pat(p)),
- expr: expr.lift(|e| folder.fold_expr(e)),
- body: folder.fold_block(body),
- label: label.map(|i| folder.fold_ident(i)),
+ pat: e.pat.lift(|p| folder.fold_pat(p)),
+ expr: e.expr.lift(|e| folder.fold_expr(e)),
+ body: folder.fold_block(e.body),
+ label: e.label.map(|i| folder.fold_ident(i)),
+ ..e
})
}
- ForLoop(ExprForLoop { pat, expr, body, label }) => {
+ ForLoop(e) => {
ForLoop(ExprForLoop {
- pat: pat.lift(|p| folder.fold_pat(p)),
- expr: expr.lift(|e| folder.fold_expr(e)),
- body: folder.fold_block(body),
- label: label.map(|i| folder.fold_ident(i)),
+ pat: e.pat.lift(|p| folder.fold_pat(p)),
+ expr: e.expr.lift(|e| folder.fold_expr(e)),
+ body: folder.fold_block(e.body),
+ label: e.label.map(|i| folder.fold_ident(i)),
+ ..e
})
}
- Loop(ExprLoop { body, label }) => {
+ Loop(e) => {
Loop(ExprLoop {
- body: folder.fold_block(body),
- label: label.map(|i| folder.fold_ident(i)),
+ body: folder.fold_block(e.body),
+ label: e.label.map(|i| folder.fold_ident(i)),
+ ..e
})
}
- Match(ExprMatch { expr, arms }) => {
+ Match(e) => {
Match(ExprMatch {
- expr: expr.lift(|e| folder.fold_expr(e)),
- arms: arms.lift(|Arm { attrs, pats, guard, body }: Arm| {
+ expr: e.expr.lift(|e| folder.fold_expr(e)),
+ arms: e.arms.lift(|a: Arm| {
Arm {
- attrs: attrs.lift(|a| folder.fold_attribute(a)),
- pats: pats.lift(|p| folder.fold_pat(p)),
- guard: guard.map(|v| v.lift(|e| folder.fold_expr(e))),
- body: body.lift(|e| folder.fold_expr(e)),
+ attrs: a.attrs.lift(|a| folder.fold_attribute(a)),
+ pats: a.pats.lift(|p| folder.fold_pat(p)),
+ guard: a.guard.map(|v| v.lift(|e| folder.fold_expr(e))),
+ body: a.body.lift(|e| folder.fold_expr(e)),
+ ..a
}
- })
+ }),
+ ..e
})
}
- Catch(ExprCatch { block }) => {
- Catch(ExprCatch { block: folder.fold_block(block) })
+ Catch(e) => {
+ Catch(ExprCatch {
+ block: folder.fold_block(e.block),
+ ..e
+ })
}
- Closure(ExprClosure { capture, decl, body }) => {
+ Closure(e) => {
Closure(ExprClosure {
- capture: capture,
- decl: decl.lift(|v| folder.fold_fn_decl(v)),
- body: body.lift(|e| folder.fold_expr(e)),
+ decl: e.decl.lift(|v| folder.fold_fn_decl(v)),
+ body: e.body.lift(|e| folder.fold_expr(e)),
+ ..e
})
}
- Block(ExprBlock { unsafety, block }) => {
+ Block(e) => {
Block(ExprBlock {
- unsafety: unsafety,
- block: folder.fold_block(block),
+ block: folder.fold_block(e.block),
+ ..e
})
}
- Assign(ExprAssign { left, right }) => {
+ Assign(e) => {
Assign(ExprAssign {
- left: left.lift(|e| folder.fold_expr(e)),
- right: right.lift(|e| folder.fold_expr(e)),
+ left: e.left.lift(|e| folder.fold_expr(e)),
+ right: e.right.lift(|e| folder.fold_expr(e)),
+ ..e
})
}
- AssignOp(ExprAssignOp { op, left, right }) => {
+ AssignOp(e) => {
AssignOp(ExprAssignOp {
- op: op,
- left: left.lift(|e| folder.fold_expr(e)),
- right: right.lift(|e| folder.fold_expr(e)),
+ left: e.left.lift(|e| folder.fold_expr(e)),
+ right: e.right.lift(|e| folder.fold_expr(e)),
+ ..e
})
}
- Field(ExprField { expr, field }) => {
+ Field(e) => {
Field(ExprField {
- expr: expr.lift(|e| folder.fold_expr(e)),
- field: folder.fold_ident(field),
+ expr: e.expr.lift(|e| folder.fold_expr(e)),
+ field: folder.fold_ident(e.field),
+ ..e
})
}
- TupField(ExprTupField { expr, field }) => {
+ TupField(e) => {
TupField(ExprTupField {
- expr: expr.lift(|e| folder.fold_expr(e)),
- field: field,
+ expr: e.expr.lift(|e| folder.fold_expr(e)),
+ ..e
})
}
- Index(ExprIndex { expr, index }) => {
+ Index(e) => {
Index(ExprIndex {
- expr: expr.lift(|e| folder.fold_expr(e)),
- index: index.lift(|e| folder.fold_expr(e)),
+ expr: e.expr.lift(|e| folder.fold_expr(e)),
+ index: e.index.lift(|e| folder.fold_expr(e)),
+ ..e
})
}
- Range(ExprRange { from, to, limits }) => {
+ Range(e) => {
Range(ExprRange {
- from: from.map(|v| v.lift(|e| folder.fold_expr(e))),
- to: to.map(|v| v.lift(|e| folder.fold_expr(e))),
- limits: limits,
+ from: e.from.map(|v| v.lift(|e| folder.fold_expr(e))),
+ to: e.to.map(|v| v.lift(|e| folder.fold_expr(e))),
+ ..e
})
}
- Path(ExprPath { qself, path }) => {
+ Path(e) => {
Path(ExprPath {
- qself: qself.map(|v| noop_fold_qself(folder, v)),
- path: folder.fold_path(path),
+ qself: e.qself.map(|v| noop_fold_qself(folder, v)),
+ path: folder.fold_path(e.path),
})
}
- AddrOf(ExprAddrOf { mutbl, expr }) => {
+ AddrOf(e) => {
AddrOf(ExprAddrOf {
- mutbl: mutbl,
- expr: expr.lift(|e| folder.fold_expr(e)),
+ expr: e.expr.lift(|e| folder.fold_expr(e)),
+ ..e
})
}
- Break(ExprBreak { label, expr }) => {
+ Break(e) => {
Break(ExprBreak {
- label: label.map(|i| folder.fold_ident(i)),
- expr: expr.map(|v| v.lift(|e| folder.fold_expr(e))),
+ label: e.label.map(|i| folder.fold_ident(i)),
+ expr: e.expr.map(|v| v.lift(|e| folder.fold_expr(e))),
+ ..e
})
}
- Continue(ExprContinue { label }) => {
+ Continue(e) => {
Continue(ExprContinue {
- label: label.map(|i| folder.fold_ident(i)),
+ label: e.label.map(|i| folder.fold_ident(i)),
+ ..e
})
}
- Ret(ExprRet { expr }) => {
+ Ret(e) => {
Ret(ExprRet {
- expr: expr.map(|v| v.lift(|e| folder.fold_expr(e))),
+ expr: e.expr.map(|v| v.lift(|e| folder.fold_expr(e))),
+ ..e
})
}
Mac(mac) => Mac(folder.fold_mac(mac)),
- Struct(ExprStruct { path, fields, rest }) => {
+ Struct(e) => {
Struct(ExprStruct {
- path: folder.fold_path(path),
- fields: fields.lift(|FieldValue { ident, expr, is_shorthand, attrs }: FieldValue| {
+ path: folder.fold_path(e.path),
+ fields: e.fields.lift(|field: FieldValue| {
FieldValue {
- ident: folder.fold_ident(ident),
- expr: folder.fold_expr(expr),
- is_shorthand: is_shorthand,
- attrs: attrs.lift(|v| folder.fold_attribute(v)),
+ ident: folder.fold_ident(field.ident),
+ expr: folder.fold_expr(field.expr),
+ attrs: field.attrs.lift(|v| folder.fold_attribute(v)),
+ ..field
}
}),
- rest: rest.map(|v| v.lift(|e| folder.fold_expr(e))),
+ rest: e.rest.map(|v| v.lift(|e| folder.fold_expr(e))),
+ ..e
})
}
- Repeat(ExprRepeat { expr, amt }) => {
+ Repeat(e) => {
Repeat(ExprRepeat {
- expr: expr.lift(|e| folder.fold_expr(e)),
- amt: amt.lift(|e| folder.fold_expr(e)),
+ expr: e.expr.lift(|e| folder.fold_expr(e)),
+ amt: e.amt.lift(|e| folder.fold_expr(e)),
+ ..e
})
}
- Paren(ExprParen { expr }) => {
- Paren(ExprParen { expr: expr.lift(|e| folder.fold_expr(e)) })
+ Paren(e) => {
+ Paren(ExprParen {
+ expr: e.expr.lift(|e| folder.fold_expr(e)),
+ ..e
+ })
}
- Try(ExprTry { expr }) => {
- Try(ExprTry { expr: expr.lift(|e| folder.fold_expr(e)) })
+ Try(e) => {
+ Try(ExprTry {
+ expr: e.expr.lift(|e| folder.fold_expr(e)),
+ ..e
+ })
}
},
attrs: attrs.into_iter().map(|a| folder.fold_attribute(a)).collect(),
@@ -937,28 +1050,28 @@
#[cfg(feature = "full")]
pub fn noop_fold_foreign_item<F: ?Sized + Folder>(folder: &mut F,
- ForeignItem { ident, attrs, node, vis }: ForeignItem)
+ item: ForeignItem)
-> ForeignItem{
use item::*;
ForeignItem {
- ident: folder.fold_ident(ident),
- attrs: attrs.into_iter().map(|a| folder.fold_attribute(a)).collect(),
- node: match node {
- ForeignItemKind::Fn(ForeignItemFn { decl, generics }) => {
+ ident: folder.fold_ident(item.ident),
+ attrs: item.attrs.into_iter().map(|a| folder.fold_attribute(a)).collect(),
+ node: match item.node {
+ ForeignItemKind::Fn(item) => {
ForeignItemKind::Fn(ForeignItemFn {
- decl: decl.lift(|v| folder.fold_fn_decl(v)),
- generics: folder.fold_generics(generics),
+ decl: item.decl.lift(|v| folder.fold_fn_decl(v)),
})
}
- ForeignItemKind::Static(ForeignItemStatic { ty, mutbl }) => {
+ ForeignItemKind::Static(item) => {
ForeignItemKind::Static(ForeignItemStatic {
- ty: ty.lift(|v| folder.fold_ty(v)),
- mutbl: mutbl,
+ ty: item.ty.lift(|v| folder.fold_ty(v)),
+ ..item
})
}
},
- vis: noop_fold_vis(folder, vis),
+ vis: noop_fold_vis(folder, item.vis),
+ ..item
}
}
@@ -966,113 +1079,146 @@
pub fn noop_fold_pat<F: ?Sized + Folder>(folder: &mut F, pat: Pat) -> Pat {
use Pat::*;
match pat {
- Wild => Wild,
- Ident(binding_mode, ident, pat) => {
- Ident(binding_mode,
- folder.fold_ident(ident),
- pat.map(|p| p.lift(|p| folder.fold_pat(p))))
+ Wild(b) => Wild(b),
+ Ident(p) => {
+ Ident(PatIdent {
+ ident: folder.fold_ident(p.ident),
+ subpat: p.subpat.map(|p| p.lift(|p| folder.fold_pat(p))),
+ ..p
+ })
}
- Struct(path, field_patterns, dots) => {
- Struct(folder.fold_path(path),
- field_patterns.lift(|FieldPat { ident, pat, is_shorthand, attrs }: FieldPat| {
+ Struct(p) => {
+ Struct(PatStruct {
+ path: folder.fold_path(p.path),
+ fields: p.fields.lift(|field: FieldPat| {
FieldPat {
- ident: folder.fold_ident(ident),
- pat: pat.lift(|p| folder.fold_pat(p)),
- is_shorthand: is_shorthand,
- attrs: attrs.lift(|a| folder.fold_attribute(a)),
+ ident: folder.fold_ident(field.ident),
+ pat: field.pat.lift(|p| folder.fold_pat(p)),
+ attrs: field.attrs.lift(|a| folder.fold_attribute(a)),
+ ..field
}
}),
- dots)
+ ..p
+ })
}
- TupleStruct(path, pats, len) => {
- TupleStruct(folder.fold_path(path),
- pats.lift(|p| folder.fold_pat(p)),
- len)
+ TupleStruct(p) => {
+ TupleStruct(PatTupleStruct {
+ path: folder.fold_path(p.path),
+ pat: PatTuple {
+ pats: p.pat.pats.lift(|p| folder.fold_pat(p)),
+ ..p.pat
+ },
+ })
}
- Path(qself, path) => {
- Path(qself.map(|v| noop_fold_qself(folder, v)),
- folder.fold_path(path))
+ Path(p) => {
+ Path(PatPath {
+ qself: p.qself.map(|v| noop_fold_qself(folder, v)),
+ path: folder.fold_path(p.path),
+ })
}
- Tuple(pats, len) => Tuple(pats.lift(|p| folder.fold_pat(p)), len),
- Box(b) => Box(b.lift(|p| folder.fold_pat(p))),
- Ref(b, mutability) => Ref(b.lift(|p| folder.fold_pat(p)), mutability),
- Lit(expr) => Lit(expr.lift(|e| folder.fold_expr(e))),
- Range(l, r, limits) => {
- Range(l.lift(|e| folder.fold_expr(e)),
- r.lift(|e| folder.fold_expr(e)),
- limits)
+ Tuple(p) => {
+ Tuple(PatTuple {
+ pats: p.pats.lift(|p| folder.fold_pat(p)),
+ ..p
+ })
}
- Slice(lefts, pat, rights) => {
- Slice(lefts.lift(|p| folder.fold_pat(p)),
- pat.map(|v| v.lift(|p| folder.fold_pat(p))),
- rights.lift(|p| folder.fold_pat(p)))
+ Box(p) => {
+ Box(PatBox {
+ pat: p.pat.lift(|p| folder.fold_pat(p)),
+ ..p
+ })
+ }
+ Ref(p) => {
+ Ref(PatRef {
+ pat: p.pat.lift(|p| folder.fold_pat(p)),
+ ..p
+ })
+ }
+ Lit(p) => {
+ Lit(PatLit {
+ expr: p.expr.lift(|e| folder.fold_expr(e)),
+ })
+ }
+ Range(p) => {
+ Range(PatRange {
+ hi: p.hi.lift(|e| folder.fold_expr(e)),
+ lo: p.lo.lift(|e| folder.fold_expr(e)),
+ ..p
+ })
+ }
+ Slice(p) => {
+ Slice(PatSlice {
+ front: p.front.lift(|p| folder.fold_pat(p)),
+ middle: p.middle.map(|v| v.lift(|p| folder.fold_pat(p))),
+ back: p.back.lift(|p| folder.fold_pat(p)),
+ ..p
+ })
}
Mac(mac) => Mac(folder.fold_mac(mac)),
}
}
#[cfg(feature = "full")]
-pub fn noop_fold_fn_decl<F: ?Sized + Folder>(folder: &mut F,
- FnDecl { inputs, output, variadic }: FnDecl)
- -> FnDecl {
-
+pub fn noop_fold_fn_decl<F: ?Sized + Folder>(folder: &mut F, decl: FnDecl)
+ -> FnDecl
+{
FnDecl {
- inputs: inputs.lift(|a| {
+ inputs: decl.inputs.lift(|a| {
use item::*;
use FnArg::*;
match a {
- SelfRef(ArgSelfRef { lifetime, mutbl }) => {
+ SelfRef(a) => {
SelfRef(ArgSelfRef {
- lifetime: lifetime.map(|v| folder.fold_lifetime(v)),
- mutbl: mutbl,
+ lifetime: a.lifetime.map(|v| folder.fold_lifetime(v)),
+ ..a
})
}
- SelfValue(ArgSelf { mutbl } ) => {
- SelfValue(ArgSelf {
- mutbl: mutbl,
- })
- }
- Captured(ArgCaptured { pat, ty }) => {
+ SelfValue(a) => SelfValue(a),
+ Captured(a) => {
Captured(ArgCaptured {
- pat: folder.fold_pat(pat),
- ty: folder.fold_ty(ty),
+ pat: folder.fold_pat(a.pat),
+ ty: folder.fold_ty(a.ty),
+ ..a
})
}
Ignored(ty) => Ignored(folder.fold_ty(ty)),
}
}),
- output: folder.fold_fn_ret_ty(output),
- variadic: variadic,
+ output: folder.fold_fn_ret_ty(decl.output),
+ generics: folder.fold_generics(decl.generics),
+ ..decl
}
-
}
#[cfg(feature = "full")]
pub fn noop_fold_trait_item<F: ?Sized + Folder>(folder: &mut F,
- TraitItem { ident, attrs, node }: TraitItem)
+ item: TraitItem)
-> TraitItem {
use item::*;
use TraitItemKind::*;
TraitItem {
- ident: folder.fold_ident(ident),
- attrs: attrs.lift(|v| folder.fold_attribute(v)),
- node: match node {
- Const(TraitItemConst { ty, default }) => {
+ ident: folder.fold_ident(item.ident),
+ attrs: item.attrs.lift(|v| folder.fold_attribute(v)),
+ node: match item.node {
+ Const(i) => {
Const(TraitItemConst {
- ty: folder.fold_ty(ty),
- default: default.map(|v| folder.fold_expr(v)),
+ ty: folder.fold_ty(i.ty),
+ default: i.default.map(|v| folder.fold_expr(v)),
+ ..i
})
}
- Method(TraitItemMethod { sig, default }) => {
+ Method(i) => {
Method(TraitItemMethod {
- sig: folder.fold_method_sig(sig),
- default: default.map(|v| folder.fold_block(v)),
+ sig: folder.fold_method_sig(i.sig),
+ default: i.default.map(|v| folder.fold_block(v)),
+ ..i
})
}
- Type(TraitItemType { bounds, default }) => {
+ Type(i) => {
Type(TraitItemType {
- bounds: bounds.lift(|v| folder.fold_ty_param_bound(v)),
- default: default.map(|v| folder.fold_ty(v)),
+ bounds: i.bounds.lift(|v| folder.fold_ty_param_bound(v)),
+ default: i.default.map(|v| folder.fold_ty(v)),
+ ..i
})
}
Macro(mac) => Macro(folder.fold_mac(mac)),
@@ -1081,48 +1227,49 @@
}
#[cfg(feature = "full")]
-pub fn noop_fold_impl_item<F: ?Sized + Folder>(folder: &mut F,
- ImplItem { ident, vis, defaultness, attrs, node }: ImplItem)
--> ImplItem{
+pub fn noop_fold_impl_item<F: ?Sized + Folder>(folder: &mut F, item: ImplItem)
+ -> ImplItem
+{
use item::*;
use ImplItemKind::*;
ImplItem {
- ident: folder.fold_ident(ident),
- vis: noop_fold_vis(folder, vis),
- defaultness: defaultness,
- attrs: attrs.lift(|v| folder.fold_attribute(v)),
- node: match node {
- Const(ImplItemConst { ty, expr }) => {
+ ident: folder.fold_ident(item.ident),
+ vis: noop_fold_vis(folder, item.vis),
+ attrs: item.attrs.lift(|v| folder.fold_attribute(v)),
+ node: match item.node {
+ Const(i) => {
Const(ImplItemConst {
- ty: folder.fold_ty(ty),
- expr: folder.fold_expr(expr),
+ ty: folder.fold_ty(i.ty),
+ expr: folder.fold_expr(i.expr),
+ ..i
})
}
- Method(ImplItemMethod { sig, block }) => {
+ Method(i) => {
Method(ImplItemMethod {
- sig: folder.fold_method_sig(sig),
- block: folder.fold_block(block),
+ sig: folder.fold_method_sig(i.sig),
+ block: folder.fold_block(i.block),
})
}
- Type(ImplItemType { ty }) => {
+ Type(i) => {
Type(ImplItemType {
- ty: folder.fold_ty(ty),
+ ty: folder.fold_ty(i.ty),
+ ..i
})
}
Macro(mac) => Macro(folder.fold_mac(mac)),
},
+ ..item
}
}
#[cfg(feature = "full")]
-pub fn noop_fold_method_sig<F: ?Sized + Folder>(folder: &mut F, MethodSig{unsafety, constness, abi, decl, generics}:MethodSig) -> MethodSig{
+pub fn noop_fold_method_sig<F: ?Sized + Folder>(folder: &mut F, sig: MethodSig)
+ -> MethodSig
+{
MethodSig {
- unsafety: unsafety,
- constness: constness,
- abi: abi,
- decl: folder.fold_fn_decl(decl),
- generics: folder.fold_generics(generics),
+ decl: folder.fold_fn_decl(sig.decl),
+ ..sig
}
}
@@ -1134,7 +1281,7 @@
Local(local) => Local(local.lift(|l| folder.fold_local(l))),
Item(item) => Item(item.lift(|v| folder.fold_item(v))),
Expr(expr) => Expr(expr.lift(|v| folder.fold_expr(v))),
- Semi(expr) => Semi(expr.lift(|v| folder.fold_expr(v))),
+ Semi(expr, t) => Semi(expr.lift(|v| folder.fold_expr(v)), t),
Mac(mac_stmt) => {
Mac(mac_stmt.lift(|(mac, style, attrs)| {
(folder.fold_mac(mac),
@@ -1147,14 +1294,15 @@
}
#[cfg(feature = "full")]
-pub fn noop_fold_local<F: ?Sized + Folder>(folder: &mut F,
- Local { pat, ty, init, attrs }: Local)
- -> Local {
+pub fn noop_fold_local<F: ?Sized + Folder>(folder: &mut F, local: Local)
+ -> Local
+{
Local {
- pat: pat.lift(|v| folder.fold_pat(v)),
- ty: ty.map(|v| v.lift(|t| folder.fold_ty(t))),
- init: init.map(|v| v.lift(|e| folder.fold_expr(e))),
- attrs: attrs.lift(|a| folder.fold_attribute(a)),
+ pat: local.pat.lift(|v| folder.fold_pat(v)),
+ ty: local.ty.map(|v| v.lift(|t| folder.fold_ty(t))),
+ init: local.init.map(|v| v.lift(|e| folder.fold_expr(e))),
+ attrs: local.attrs.lift(|a| folder.fold_attribute(a)),
+ ..local
}
}
@@ -1163,26 +1311,30 @@
use item::*;
use ViewPath::*;
match view_path {
- Simple(PathSimple { path, rename }) => {
+ Simple(p) => {
Simple(PathSimple {
- path: folder.fold_path(path),
- rename: rename.map(|i| folder.fold_ident(i)),
+ path: folder.fold_path(p.path),
+ rename: p.rename.map(|i| folder.fold_ident(i)),
+ ..p
})
}
- Glob(PathGlob { path }) => {
+ Glob(p) => {
Glob(PathGlob {
- path: folder.fold_path(path),
+ path: folder.fold_path(p.path),
+ ..p
})
}
- List(PathList { path, items }) => {
+ List(p) => {
List(PathList {
- path: folder.fold_path(path),
- items: items.lift(|PathListItem { name, rename }: PathListItem| {
+ path: folder.fold_path(p.path),
+ items: p.items.lift(|item: PathListItem| {
PathListItem {
- name: folder.fold_ident(name),
- rename: rename.map(|i| folder.fold_ident(i)),
+ name: folder.fold_ident(item.name),
+ rename: item.rename.map(|i| folder.fold_ident(i)),
+ ..item
}
}),
+ ..p
})
}
}
diff --git a/src/generics.rs b/src/generics.rs
index adf6dfa..c6d697a 100644
--- a/src/generics.rs
+++ b/src/generics.rs
@@ -1,12 +1,15 @@
use super::*;
+use delimited::Delimited;
ast_struct! {
/// Represents lifetimes and type parameters attached to a declaration
/// of a function, enum, trait, etc.
#[derive(Default)]
pub struct Generics {
- pub lifetimes: Vec<LifetimeDef>,
- pub ty_params: Vec<TyParam>,
+ pub lt_token: Option<tokens::Lt>,
+ pub gt_token: Option<tokens::Gt>,
+ pub lifetimes: Delimited<LifetimeDef, tokens::Comma>,
+ pub ty_params: Delimited<TyParam, tokens::Comma>,
pub where_clause: WhereClause,
}
}
@@ -40,7 +43,7 @@
/// # extern crate quote;
/// # fn main() {
/// # let generics: syn::Generics = Default::default();
- /// # let name = syn::Ident::new("MyType");
+ /// # let name = syn::Ident::from("MyType");
/// let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
/// quote! {
/// impl #impl_generics MyTrait for #name #ty_generics #where_clause {
@@ -71,7 +74,7 @@
impl Lifetime {
pub fn new<T: Into<Ident>>(t: T) -> Self {
- let id = Ident::new(t);
+ let id = t.into();
if !id.as_ref().starts_with('\'') {
panic!("lifetime name must start with apostrophe as in \"'a\", \
got {:?}",
@@ -82,11 +85,23 @@
}
ast_struct! {
+ /// A set of bound lifetimes, e.g. `for<'a, 'b, 'c>`
+ #[derive(Default)]
+ pub struct BoundLifetimes {
+ pub for_token: tokens::For,
+ pub lt_token: tokens::Lt,
+ pub lifetimes: Delimited<LifetimeDef, tokens::Comma>,
+ pub gt_token: tokens::Gt,
+ }
+}
+
+ast_struct! {
/// A lifetime definition, e.g. `'a: 'b+'c+'d`
pub struct LifetimeDef {
pub attrs: Vec<Attribute>,
pub lifetime: Lifetime,
- pub bounds: Vec<Lifetime>,
+ pub colon_token: Option<tokens::Colon>,
+ pub bounds: Delimited<Lifetime, tokens::Add>,
}
}
@@ -95,7 +110,8 @@
LifetimeDef {
attrs: Vec::new(),
lifetime: Lifetime::new(t),
- bounds: Vec::new(),
+ colon_token: None,
+ bounds: Delimited::new(),
}
}
}
@@ -105,7 +121,9 @@
pub struct TyParam {
pub attrs: Vec<Attribute>,
pub ident: Ident,
- pub bounds: Vec<TyParamBound>,
+ pub colon_token: Option<tokens::Colon>,
+ pub bounds: Delimited<TyParamBound, tokens::Add>,
+ pub eq_token: Option<tokens::Eq>,
pub default: Option<Ty>,
}
}
@@ -115,7 +133,9 @@
TyParam {
attrs: vec![],
ident: ident,
- bounds: vec![],
+ colon_token: None,
+ bounds: Delimited::new(),
+ eq_token: None,
default: None,
}
}
@@ -138,7 +158,7 @@
#[cfg_attr(feature = "clone-impls", derive(Copy))]
pub enum TraitBoundModifier {
None,
- Maybe,
+ Maybe(tokens::Question),
}
}
@@ -146,13 +166,14 @@
/// A `where` clause in a definition
#[derive(Default)]
pub struct WhereClause {
- pub predicates: Vec<WherePredicate>,
+ pub where_token: Option<tokens::Where>,
+ pub predicates: Delimited<WherePredicate, tokens::Comma>,
}
}
impl WhereClause {
pub fn none() -> Self {
- WhereClause { predicates: Vec::new() }
+ WhereClause::default()
}
}
@@ -162,22 +183,25 @@
/// A type binding, e.g. `for<'c> Foo: Send+Clone+'c`
pub BoundPredicate(WhereBoundPredicate {
/// Any lifetimes from a `for` binding
- pub bound_lifetimes: Vec<LifetimeDef>,
+ pub bound_lifetimes: Option<BoundLifetimes>,
/// The type being bounded
pub bounded_ty: Ty,
+ pub colon_token: tokens::Colon,
/// Trait and lifetime bounds (`Clone+Send+'static`)
- pub bounds: Vec<TyParamBound>,
+ pub bounds: Delimited<TyParamBound, tokens::Add>,
}),
/// A lifetime predicate, e.g. `'a: 'b+'c`
pub RegionPredicate(WhereRegionPredicate {
pub lifetime: Lifetime,
- pub bounds: Vec<Lifetime>,
+ pub colon_token: Option<tokens::Colon>,
+ pub bounds: Delimited<Lifetime, tokens::Add>,
}),
/// An equality predicate (unsupported)
pub EqPredicate(WhereEqPredicate {
pub lhs_ty: Ty,
+ pub eq_token: tokens::Eq,
pub rhs_ty: Ty,
}),
}
@@ -194,22 +218,29 @@
alt!(
do_parse!(
punct!("<") >>
- lifetimes: separated_list!(punct!(","), lifetime_def) >>
- ty_params: opt_vec!(preceded!(
- cond!(!lifetimes.is_empty(), punct!(",")),
- separated_nonempty_list!(punct!(","), ty_param)
- )) >>
- cond!(!lifetimes.is_empty() || !ty_params.is_empty(), option!(punct!(","))) >>
+ lifetimes: terminated_list!(
+ map!(punct!(","), |_| tokens::Comma::default()),
+ lifetime_def
+ ) >>
+ ty_params: cond!(
+ lifetimes.is_empty() || lifetimes.trailing_delim(),
+ terminated_list!(
+ map!(punct!(","), |_| tokens::Comma::default()),
+ ty_param
+ )
+ ) >>
punct!(">") >>
- (lifetimes, ty_params)
+ (lifetimes, ty_params, true)
)
|
- epsilon!() => { |_| (Vec::new(), Vec::new()) }
+ epsilon!() => { |_| (Delimited::new(), None, false) }
),
- |(lifetimes, ty_params)| Generics {
+ |(lifetimes, ty_params, any): (_, Option<_>, _)| Generics {
lifetimes: lifetimes,
- ty_params: ty_params,
- where_clause: Default::default(),
+ ty_params: ty_params.unwrap_or_default(),
+ where_clause: WhereClause::default(),
+ gt_token: if any {Some(tokens::Gt::default())} else {None},
+ lt_token: if any {Some(tokens::Lt::default())} else {None},
}
));
@@ -229,32 +260,43 @@
named!(pub lifetime_def -> LifetimeDef, do_parse!(
attrs: many0!(outer_attr) >>
life: lifetime >>
- bounds: opt_vec!(preceded!(
- punct!(":"),
- separated_list!(punct!("+"), lifetime)
- )) >>
+ colon: option!(punct!(":")) >>
+ bounds: cond!(
+ colon.is_some(),
+ separated_nonempty_list!(map!(punct!("+"), |_| tokens::Add::default()),
+ lifetime)
+ ) >>
(LifetimeDef {
attrs: attrs,
lifetime: life,
- bounds: bounds,
+ bounds: bounds.unwrap_or_default(),
+ colon_token: colon.map(|_| tokens::Colon::default()),
})
));
- named!(pub bound_lifetimes -> Vec<LifetimeDef>, opt_vec!(do_parse!(
+ named!(pub bound_lifetimes -> Option<BoundLifetimes>, option!(do_parse!(
keyword!("for") >>
punct!("<") >>
- lifetimes: terminated_list!(punct!(","), lifetime_def) >>
+ lifetimes: terminated_list!(map!(punct!(","), |_| tokens::Comma::default()),
+ lifetime_def) >>
punct!(">") >>
- (lifetimes)
+ (BoundLifetimes {
+ for_token: tokens::For::default(),
+ lt_token: tokens::Lt::default(),
+ gt_token: tokens::Gt::default(),
+ lifetimes: lifetimes,
+ })
)));
named!(ty_param -> TyParam, do_parse!(
attrs: many0!(outer_attr) >>
id: ident >>
- bounds: opt_vec!(preceded!(
- punct!(":"),
- separated_nonempty_list!(punct!("+"), ty_param_bound)
- )) >>
+ colon: option!(punct!(":")) >>
+ bounds: cond!(
+ colon.is_some(),
+ separated_nonempty_list!(map!(punct!("+"), |_| tokens::Add::default()),
+ ty_param_bound)
+ ) >>
default: option!(preceded!(
punct!("="),
ty
@@ -262,14 +304,16 @@
(TyParam {
attrs: attrs,
ident: id,
- bounds: bounds,
+ bounds: bounds.unwrap_or_default(),
+ colon_token: colon.map(|_| tokens::Colon::default()),
+ eq_token: default.as_ref().map(|_| tokens::Eq::default()),
default: default,
})
));
named!(pub ty_param_bound -> TyParamBound, alt!(
preceded!(punct!("?"), poly_trait_ref) => {
- |poly| TyParamBound::Trait(poly, TraitBoundModifier::Maybe)
+ |poly| TyParamBound::Trait(poly, TraitBoundModifier::Maybe(tokens::Question::default()))
}
|
lifetime => { TyParamBound::Region }
@@ -282,24 +326,32 @@
named!(pub where_clause -> WhereClause, alt!(
do_parse!(
keyword!("where") >>
- predicates: separated_nonempty_list!(punct!(","), where_predicate) >>
- option!(punct!(",")) >>
- (WhereClause { predicates: predicates })
+ predicates: terminated_list!(
+ map!(punct!(","), |_| tokens::Comma::default()),
+ where_predicate
+ ) >>
+ (WhereClause {
+ predicates: predicates,
+ where_token: Some(tokens::Where::default()),
+ })
)
|
- epsilon!() => { |_| Default::default() }
+ epsilon!() => { |_| WhereClause::default() }
));
named!(where_predicate -> WherePredicate, alt!(
do_parse!(
ident: lifetime >>
- bounds: opt_vec!(preceded!(
- punct!(":"),
- separated_list!(punct!("+"), lifetime)
- )) >>
+ colon: option!(punct!(":")) >>
+ bounds: cond!(
+ colon.is_some(),
+ separated_list!(map!(punct!("+"), |_| tokens::Add::default()),
+ lifetime)
+ ) >>
(WherePredicate::RegionPredicate(WhereRegionPredicate {
lifetime: ident,
- bounds: bounds,
+ bounds: bounds.unwrap_or_default(),
+ colon_token: colon.map(|_| tokens::Colon::default()),
}))
)
|
@@ -307,11 +359,13 @@
bound_lifetimes: bound_lifetimes >>
bounded_ty: ty >>
punct!(":") >>
- bounds: separated_nonempty_list!(punct!("+"), ty_param_bound) >>
+ bounds: separated_nonempty_list!(map!(punct!("+"), |_| tokens::Add::default()),
+ ty_param_bound) >>
(WherePredicate::BoundPredicate(WhereBoundPredicate {
bound_lifetimes: bound_lifetimes,
bounded_ty: bounded_ty,
bounds: bounds,
+ colon_token: tokens::Colon::default(),
}))
)
));
@@ -325,70 +379,44 @@
impl ToTokens for Generics {
fn to_tokens(&self, tokens: &mut Tokens) {
- let has_lifetimes = !self.lifetimes.is_empty();
- let has_ty_params = !self.ty_params.is_empty();
- if has_lifetimes || has_ty_params {
- tokens.append("<");
- tokens.append_separated(&self.lifetimes, ",");
- if has_lifetimes && has_ty_params {
- tokens.append(",");
- }
- tokens.append_separated(&self.ty_params, ",");
- tokens.append(">");
- }
+ self.lt_token.to_tokens(tokens);
+ self.lifetimes.to_tokens(tokens);
+ self.ty_params.to_tokens(tokens);
+ self.gt_token.to_tokens(tokens);
}
}
impl<'a> ToTokens for ImplGenerics<'a> {
fn to_tokens(&self, tokens: &mut Tokens) {
- let has_lifetimes = !self.0.lifetimes.is_empty();
- let has_ty_params = !self.0.ty_params.is_empty();
- if has_lifetimes || has_ty_params {
- tokens.append("<");
- tokens.append_separated(&self.0.lifetimes, ",");
- // Leave off the type parameter defaults
- for (i, ty_param) in self.0
- .ty_params
- .iter()
- .enumerate() {
- if i > 0 || has_lifetimes {
- tokens.append(",");
- }
- tokens.append_all(ty_param.attrs.outer());
- ty_param.ident.to_tokens(tokens);
- if !ty_param.bounds.is_empty() {
- tokens.append(":");
- tokens.append_separated(&ty_param.bounds, "+");
- }
- }
- tokens.append(">");
+ self.0.lt_token.to_tokens(tokens);
+ self.0.lifetimes.to_tokens(tokens);
+ for param in self.0.ty_params.iter() {
+ // Leave off the type parameter defaults
+ let item = param.item();
+ tokens.append_all(item.attrs.outer());
+ item.ident.to_tokens(tokens);
+ item.colon_token.to_tokens(tokens);
+ item.bounds.to_tokens(tokens);
+ param.delimiter().to_tokens(tokens);
}
+ self.0.gt_token.to_tokens(tokens);
}
}
impl<'a> ToTokens for TyGenerics<'a> {
fn to_tokens(&self, tokens: &mut Tokens) {
- let has_lifetimes = !self.0.lifetimes.is_empty();
- let has_ty_params = !self.0.ty_params.is_empty();
- if has_lifetimes || has_ty_params {
- tokens.append("<");
- // Leave off the lifetime bounds and attributes
- let lifetimes = self.0
- .lifetimes
- .iter()
- .map(|ld| &ld.lifetime);
- tokens.append_separated(lifetimes, ",");
- if has_lifetimes && has_ty_params {
- tokens.append(",");
- }
- // Leave off the type parameter bounds, defaults, and attributes
- let ty_params = self.0
- .ty_params
- .iter()
- .map(|tp| &tp.ident);
- tokens.append_separated(ty_params, ",");
- tokens.append(">");
+ self.0.lt_token.to_tokens(tokens);
+ // Leave off the lifetime bounds and attributes
+ for param in self.0.lifetimes.iter() {
+ param.item().lifetime.to_tokens(tokens);
+ param.delimiter().to_tokens(tokens);
}
+ // Leave off the type parameter defaults
+ for param in self.0.ty_params.iter() {
+ param.item().ident.to_tokens(tokens);
+ param.delimiter().to_tokens(tokens);
+ }
+ self.0.gt_token.to_tokens(tokens);
}
}
@@ -397,7 +425,7 @@
let has_lifetimes = !self.0.lifetimes.is_empty();
let has_ty_params = !self.0.ty_params.is_empty();
if has_lifetimes || has_ty_params {
- tokens.append("::");
+ tokens::Colon2::default().to_tokens(tokens);
TyGenerics(self.0).to_tokens(tokens);
}
}
@@ -409,14 +437,21 @@
}
}
+ impl ToTokens for BoundLifetimes {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ self.for_token.to_tokens(tokens);
+ self.lt_token.to_tokens(tokens);
+ self.lifetimes.to_tokens(tokens);
+ self.gt_token.to_tokens(tokens);
+ }
+ }
+
impl ToTokens for LifetimeDef {
fn to_tokens(&self, tokens: &mut Tokens) {
tokens.append_all(self.attrs.outer());
self.lifetime.to_tokens(tokens);
- if !self.bounds.is_empty() {
- tokens.append(":");
- tokens.append_separated(&self.bounds, "+");
- }
+ self.colon_token.to_tokens(tokens);
+ self.bounds.to_tokens(tokens);
}
}
@@ -424,14 +459,10 @@
fn to_tokens(&self, tokens: &mut Tokens) {
tokens.append_all(self.attrs.outer());
self.ident.to_tokens(tokens);
- if !self.bounds.is_empty() {
- tokens.append(":");
- tokens.append_separated(&self.bounds, "+");
- }
- if let Some(ref default) = self.default {
- tokens.append("=");
- default.to_tokens(tokens);
- }
+ self.colon_token.to_tokens(tokens);
+ self.bounds.to_tokens(tokens);
+ self.eq_token.to_tokens(tokens);
+ self.default.to_tokens(tokens);
}
}
@@ -440,55 +471,50 @@
match *self {
TyParamBound::Region(ref lifetime) => lifetime.to_tokens(tokens),
TyParamBound::Trait(ref trait_ref, ref modifier) => {
- match *modifier {
- TraitBoundModifier::None => {}
- TraitBoundModifier::Maybe => tokens.append("?"),
- }
+ modifier.to_tokens(tokens);
trait_ref.to_tokens(tokens);
}
}
}
}
+ impl ToTokens for TraitBoundModifier {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ match *self {
+ TraitBoundModifier::None => {}
+ TraitBoundModifier::Maybe(ref t) => t.to_tokens(tokens),
+ }
+ }
+ }
+
impl ToTokens for WhereClause {
fn to_tokens(&self, tokens: &mut Tokens) {
- if !self.predicates.is_empty() {
- tokens.append("where");
- tokens.append_separated(&self.predicates, ",");
- }
+ self.where_token.to_tokens(tokens);
+ self.predicates.to_tokens(tokens);
}
}
impl ToTokens for WhereBoundPredicate {
fn to_tokens(&self, tokens: &mut Tokens) {
- if !self.bound_lifetimes.is_empty() {
- tokens.append("for");
- tokens.append("<");
- tokens.append_separated(&self.bound_lifetimes, ",");
- tokens.append(">");
- }
+ self.bound_lifetimes.to_tokens(tokens);
self.bounded_ty.to_tokens(tokens);
- if !self.bounds.is_empty() {
- tokens.append(":");
- tokens.append_separated(&self.bounds, "+");
- }
+ self.colon_token.to_tokens(tokens);
+ self.bounds.to_tokens(tokens);
}
}
impl ToTokens for WhereRegionPredicate {
fn to_tokens(&self, tokens: &mut Tokens) {
self.lifetime.to_tokens(tokens);
- if !self.bounds.is_empty() {
- tokens.append(":");
- tokens.append_separated(&self.bounds, "+");
- }
+ self.colon_token.to_tokens(tokens);
+ self.bounds.to_tokens(tokens);
}
}
impl ToTokens for WhereEqPredicate {
fn to_tokens(&self, tokens: &mut Tokens) {
self.lhs_ty.to_tokens(tokens);
- tokens.append("=");
+ self.eq_token.to_tokens(tokens);
self.rhs_ty.to_tokens(tokens);
}
}
diff --git a/src/ident.rs b/src/ident.rs
index 8f698be..3df1b61 100644
--- a/src/ident.rs
+++ b/src/ident.rs
@@ -1,48 +1,66 @@
use std::borrow::Cow;
+use std::cmp::Ordering;
use std::fmt::{self, Display};
+use std::hash::{Hash, Hasher};
-#[derive(Debug, Clone, Eq, Hash, Ord, PartialOrd)]
-pub struct Ident(String);
+use proc_macro2::Symbol;
+
+use Span;
+
+#[derive(Clone)]
+pub struct Ident {
+ pub sym: Symbol,
+ pub span: Span,
+}
impl Ident {
- pub fn new<T: Into<Ident>>(t: T) -> Self {
- t.into()
+ pub fn new(sym: Symbol, span: Span) -> Self {
+ Ident {
+ sym: sym,
+ span: span,
+ }
}
}
impl<'a> From<&'a str> for Ident {
fn from(s: &str) -> Self {
- Ident(s.to_owned())
+ Ident::new(s.into(), Span::default())
}
}
impl<'a> From<Cow<'a, str>> for Ident {
fn from(s: Cow<'a, str>) -> Self {
- Ident(s.into_owned())
+ Ident::new(s[..].into(), Span::default())
}
}
impl From<String> for Ident {
fn from(s: String) -> Self {
- Ident(s)
+ Ident::new(s[..].into(), Span::default())
}
}
impl From<usize> for Ident {
fn from(u: usize) -> Self {
- Ident(u.to_string())
+ Ident::new(u.to_string()[..].into(), Span::default())
}
}
impl AsRef<str> for Ident {
fn as_ref(&self) -> &str {
- &self.0
+ self.sym.as_str()
}
}
impl Display for Ident {
- fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
- self.0.fmt(formatter)
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.sym.as_str().fmt(formatter)
+ }
+}
+
+impl fmt::Debug for Ident {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ fmt::Debug::fmt(self.sym.as_str(), formatter)
}
}
@@ -50,7 +68,27 @@
where T: AsRef<str>
{
fn eq(&self, other: &T) -> bool {
- self.0 == other.as_ref()
+ self.as_ref() == other.as_ref()
+ }
+}
+
+impl Eq for Ident {}
+
+impl PartialOrd for Ident {
+ fn partial_cmp(&self, other: &Ident) -> Option<Ordering> {
+ Some(self.cmp(other))
+ }
+}
+
+impl Ord for Ident {
+ fn cmp(&self, other: &Ident) -> Ordering {
+ self.as_ref().cmp(other.as_ref())
+ }
+}
+
+impl Hash for Ident {
+ fn hash<H: Hasher>(&self, h: &mut H) {
+ self.as_ref().hash(h)
}
}
@@ -120,10 +158,14 @@
mod printing {
use super::*;
use quote::{Tokens, ToTokens};
+ use proc_macro2::{TokenTree, TokenKind};
impl ToTokens for Ident {
fn to_tokens(&self, tokens: &mut Tokens) {
- tokens.append(self.as_ref())
+ tokens.append(TokenTree {
+ span: self.span.0,
+ kind: TokenKind::Word(self.sym),
+ })
}
}
}
diff --git a/src/item.rs b/src/item.rs
index 611e52a..f7373a6 100644
--- a/src/item.rs
+++ b/src/item.rs
@@ -1,4 +1,5 @@
use super::*;
+use delimited::Delimited;
ast_struct! {
/// An item
@@ -18,18 +19,28 @@
///
/// E.g. `extern crate foo` or `extern crate foo_bar as foo`
pub ExternCrate(ItemExternCrate {
+ pub extern_token: tokens::Extern,
+ pub crate_token: tokens::Crate,
+ pub as_token: Option<tokens::As>,
pub original: Option<Ident>,
+ pub semi_token: tokens::Semi,
}),
/// A use declaration (`use` or `pub use`) item.
///
/// E.g. `use foo;`, `use foo::bar;` or `use foo::bar as FooBar;`
pub Use(ItemUse {
+ pub use_token: tokens::Use,
pub path: Box<ViewPath>,
+ pub semi_token: tokens::Semi,
}),
/// A static item (`static` or `pub static`).
///
/// E.g. `static FOO: i32 = 42;` or `static FOO: &'static str = "bar";`
pub Static(ItemStatic {
+ pub static_token: tokens::Static,
+ pub colon_token: tokens::Colon,
+ pub eq_token: tokens::Eq,
+ pub semi_token: tokens::Semi,
pub ty: Box<Ty>,
pub mutbl: Mutability,
pub expr: Box<Expr>,
@@ -38,6 +49,10 @@
///
/// E.g. `const FOO: i32 = 42;`
pub Const(ItemConst {
+ pub const_token: tokens::Const,
+ pub colon_token: tokens::Colon,
+ pub eq_token: tokens::Eq,
+ pub semi_token: tokens::Semi,
pub ty: Box<Ty>,
pub expr: Box<Expr>,
}),
@@ -49,23 +64,32 @@
pub unsafety: Unsafety,
pub constness: Constness,
pub abi: Option<Abi>,
- pub generics: Generics,
pub block: Box<Block>,
}),
/// A module declaration (`mod` or `pub mod`).
///
/// E.g. `mod foo;` or `mod foo { .. }`
pub Mod(ItemMod {
- pub items: Option<Vec<Item>>,
+ pub mod_token: tokens::Mod,
+ pub semi_token: Option<tokens::Semi>,
+ pub items: Option<(Vec<Item>, tokens::Brace)>,
}),
/// An external module (`extern` or `pub extern`).
///
/// E.g. `extern {}` or `extern "C" {}`
- pub ForeignMod(ItemForeignMod),
+ pub ForeignMod(ItemForeignMod {
+ pub brace_token: tokens::Brace,
+ pub abi: Abi,
+ pub items: Vec<ForeignItem>,
+ }),
+
/// A type alias (`type` or `pub type`).
///
/// E.g. `type Foo = Bar<u8>;`
pub Ty(ItemTy {
+ pub type_token: tokens::Type,
+ pub eq_token: tokens::Eq,
+ pub semi_token: tokens::Semi,
pub ty: Box<Ty>,
pub generics: Generics,
}),
@@ -73,20 +97,25 @@
///
/// E.g. `enum Foo<A, B> { C<A>, D<B> }`
pub Enum(ItemEnum {
- pub variants: Vec<Variant>,
+ pub enum_token: tokens::Enum,
+ pub brace_token: tokens::Brace,
+ pub variants: Delimited<Variant, tokens::Comma>,
pub generics: Generics,
}),
/// A struct definition (`struct` or `pub struct`).
///
/// E.g. `struct Foo<A> { x: A }`
pub Struct(ItemStruct {
+ pub struct_token: tokens::Struct,
pub data: VariantData,
pub generics: Generics,
+ pub semi_token: Option<tokens::Semi>,
}),
/// A union definition (`union` or `pub union`).
///
/// E.g. `union Foo<A, B> { x: A, y: B }`
pub Union(ItemUnion {
+ pub union_token: tokens::Union,
pub data: VariantData,
pub generics: Generics,
}),
@@ -94,9 +123,12 @@
///
/// E.g. `trait Foo { .. }` or `trait Foo<T> { .. }`
pub Trait(ItemTrait {
+ pub trait_token: tokens::Trait,
pub unsafety: Unsafety,
pub generics: Generics,
- pub supertraits: Vec<TyParamBound>,
+ pub colon_token: Option<tokens::Colon>,
+ pub supertraits: Delimited<TyParamBound, tokens::Add>,
+ pub brace_token: tokens::Brace,
pub items: Vec<TraitItem>,
}),
/// Default trait implementation.
@@ -105,16 +137,23 @@
pub DefaultImpl(ItemDefaultImpl {
pub unsafety: Unsafety,
pub path: Path,
+ pub impl_token: tokens::Impl,
+ pub for_token: tokens::For,
+ pub dot2_token: tokens::Dot2,
+ pub brace_token: tokens::Brace,
}),
/// An implementation.
///
/// E.g. `impl<A> Foo<A> { .. }` or `impl<A> Trait for Foo<A> { .. }`
pub Impl(ItemImpl {
+ pub impl_token: tokens::Impl,
pub unsafety: Unsafety,
pub polarity: ImplPolarity,
pub generics: Generics,
+ pub for_token: Option<tokens::For>,
pub trait_: Option<Path>, // (optional) trait this impl implements
pub self_ty: Box<Ty>, // self
+ pub brace_token: tokens::Brace,
pub items: Vec<ImplItem>,
}),
/// A macro invocation (which includes macro definition).
@@ -133,16 +172,20 @@
vis: input.vis,
attrs: input.attrs,
node: match input.body {
- Body::Enum(variants) => {
+ Body::Enum(data) => {
ItemEnum {
- variants: variants,
+ variants: data.variants,
generics: input.generics,
+ brace_token: data.brace_token,
+ enum_token: data.enum_token,
}.into()
}
- Body::Struct(variant_data) => {
+ Body::Struct(data) => {
ItemStruct {
- data: variant_data,
+ data: data.data,
generics: input.generics,
+ semi_token: data.semi_token,
+ struct_token: data.struct_token,
}.into()
}
},
@@ -159,18 +202,23 @@
/// `foo::bar::baz` (with `as baz` implicitly on the right)
pub Simple(PathSimple {
pub path: Path,
+ pub as_token: Option<tokens::As>,
pub rename: Option<Ident>,
}),
/// `foo::bar::*`
pub Glob(PathGlob {
pub path: Path,
+ pub colon2_token: tokens::Colon2,
+ pub star_token: tokens::Star,
}),
/// `foo::bar::{a, b, c}`
pub List(PathList {
pub path: Path,
- pub items: Vec<PathListItem>,
+ pub colon2_token: tokens::Colon2,
+ pub brace_token: tokens::Brace,
+ pub items: Delimited<PathListItem, tokens::Comma>,
}),
}
}
@@ -180,13 +228,14 @@
pub name: Ident,
/// renamed in list, e.g. `use foo::{bar as baz};`
pub rename: Option<Ident>,
+ pub as_token: Option<tokens::As>,
}
}
ast_enum! {
#[cfg_attr(feature = "clone-impls", derive(Copy))]
pub enum Constness {
- Const,
+ Const(tokens::Const),
NotConst,
}
}
@@ -194,27 +243,18 @@
ast_enum! {
#[cfg_attr(feature = "clone-impls", derive(Copy))]
pub enum Defaultness {
- Default,
+ Default(tokens::Default),
Final,
}
}
ast_struct! {
- /// Foreign module declaration.
- ///
- /// E.g. `extern { .. }` or `extern "C" { .. }`
- pub struct ItemForeignMod {
- pub abi: Abi,
- pub items: Vec<ForeignItem>,
- }
-}
-
-ast_struct! {
pub struct ForeignItem {
pub ident: Ident,
pub attrs: Vec<Attribute>,
pub node: ForeignItemKind,
pub vis: Visibility,
+ pub semi_token: tokens::Semi,
}
}
@@ -224,11 +264,12 @@
/// A foreign function
pub Fn(ForeignItemFn {
pub decl: Box<FnDecl>,
- pub generics: Generics,
}),
/// A foreign static item (`static ext: u8`)
pub Static(ForeignItemStatic {
+ pub static_token: tokens::Static,
pub ty: Box<Ty>,
+ pub colon_token: tokens::Colon,
pub mutbl: Mutability,
}),
}
@@ -251,16 +292,25 @@
ast_enum_of_structs! {
pub enum TraitItemKind {
pub Const(TraitItemConst {
+ pub const_token: tokens::Const,
+ pub colon_token: tokens::Colon,
pub ty: Ty,
pub default: Option<Expr>,
+ pub eq_token: Option<tokens::Eq>,
+ pub semi_token: tokens::Semi,
}),
pub Method(TraitItemMethod {
pub sig: MethodSig,
pub default: Option<Block>,
+ pub semi_token: Option<tokens::Semi>,
}),
pub Type(TraitItemType {
- pub bounds: Vec<TyParamBound>,
+ pub type_token: tokens::Type,
+ pub colon_token: Option<tokens::Colon>,
+ pub bounds: Delimited<TyParamBound, tokens::Add>,
+ pub eq_token: Option<tokens::Eq>,
pub default: Option<Ty>,
+ pub semi_token: tokens::Semi,
}),
pub Macro(Mac),
}
@@ -274,7 +324,7 @@
/// `impl Trait for Type`
Positive,
/// `impl !Trait for Type`
- Negative,
+ Negative(tokens::Bang),
}
}
@@ -291,6 +341,10 @@
ast_enum_of_structs! {
pub enum ImplItemKind {
pub Const(ImplItemConst {
+ pub const_token: tokens::Const,
+ pub colon_token: tokens::Colon,
+ pub eq_token: tokens::Eq,
+ pub semi_token: tokens::Semi,
pub ty: Ty,
pub expr: Expr,
}),
@@ -299,6 +353,9 @@
pub block: Block,
}),
pub Type(ImplItemType {
+ pub type_token: tokens::Type,
+ pub eq_token: tokens::Eq,
+ pub semi_token: tokens::Semi,
pub ty: Ty,
}),
pub Macro(Mac),
@@ -315,7 +372,6 @@
pub constness: Constness,
pub abi: Option<Abi>,
pub decl: FnDecl,
- pub generics: Generics,
}
}
@@ -324,9 +380,13 @@
///
/// E.g. `fn foo(bar: baz)`
pub struct FnDecl {
- pub inputs: Vec<FnArg>,
+ pub fn_token: tokens::Fn,
+ pub paren_token: tokens::Paren,
+ pub inputs: Delimited<FnArg, tokens::Comma>,
pub output: FunctionRetTy,
+ pub generics: Generics,
pub variadic: bool,
+ pub dot_tokens: Option<tokens::Dot3>,
}
}
@@ -336,14 +396,18 @@
/// E.g. `bar: usize` as in `fn foo(bar: usize)`
pub enum FnArg {
pub SelfRef(ArgSelfRef {
+ pub and_token: tokens::And,
+ pub self_token: tokens::Self_,
pub lifetime: Option<Lifetime>,
pub mutbl: Mutability,
}),
pub SelfValue(ArgSelf {
pub mutbl: Mutability,
+ pub self_token: tokens::Self_,
}),
pub Captured(ArgCaptured {
pub pat: Pat,
+ pub colon_token: tokens::Colon,
pub ty: Ty,
}),
pub Ignored(Ty),
@@ -353,8 +417,7 @@
#[cfg(feature = "parsing")]
pub mod parsing {
use super::*;
- use {Block, DelimToken, FunctionRetTy, Generics, Ident, Mac, Path, TokenTree, VariantData,
- Visibility};
+ use {Block, Generics, Ident, Mac, Path, VariantData};
use attr::parsing::{inner_attr, outer_attr};
use data::parsing::{struct_like_body, visibility};
use expr::parsing::{expr, pat, within_block};
@@ -363,7 +426,7 @@
use mac::parsing::delimited;
use derive::{Body, DeriveInput};
use derive::parsing::derive_input;
- use ty::parsing::{abi, mutability, path, ty, unsafety};
+ use ty::parsing::{abi, mutability, path, ty, unsafety, fn_ret_ty};
named!(pub item -> Item, alt!(
item_extern_crate
@@ -403,17 +466,15 @@
punct!("!") >>
name: option!(ident) >>
body: delimited >>
- cond!(match body.delim {
- DelimToken::Paren | DelimToken::Bracket => true,
- DelimToken::Brace => false,
- }, punct!(";")) >>
+ cond!(!body.is_braced(), punct!(";")) >>
(Item {
- ident: name.unwrap_or_else(|| Ident::new("")),
- vis: Visibility::Inherited,
+ ident: name.unwrap_or_else(|| Ident::from("")),
+ vis: VisInherited {}.into(),
attrs: attrs,
node: ItemKind::Mac(Mac {
+ bang_token: tokens::Bang::default(),
path: what,
- tts: vec![TokenTree::Delimited(body)],
+ tokens: vec![body],
}),
})
));
@@ -438,7 +499,13 @@
ident: name,
vis: vis,
attrs: attrs,
- node: ItemExternCrate { original: original_name }.into(),
+ node: ItemExternCrate {
+ as_token: original_name.as_ref().map(|_| tokens::As::default()),
+ original: original_name,
+ extern_token: tokens::Extern::default(),
+ crate_token: tokens::Crate::default(),
+ semi_token: tokens::Semi::default(),
+ }.into(),
}
})
));
@@ -453,7 +520,11 @@
ident: "".into(),
vis: vis,
attrs: attrs,
- node: ItemUse { path: Box::new(what) }.into(),
+ node: ItemUse {
+ path: Box::new(what),
+ use_token: tokens::Use::default(),
+ semi_token: tokens::Semi::default(),
+ }.into(),
})
));
@@ -471,35 +542,53 @@
named!(view_path_simple -> ViewPath, do_parse!(
path: path >>
rename: option!(preceded!(keyword!("as"), ident)) >>
- (PathSimple { path: path, rename: rename }.into())
+ (PathSimple {
+ path: path,
+ as_token: rename.as_ref().map(|_| tokens::As::default()),
+ rename: rename,
+ }.into())
));
named!(view_path_glob -> ViewPath, do_parse!(
path: path >>
punct!("::") >>
punct!("*") >>
- (PathGlob { path: path }.into())
+ (PathGlob {
+ path: path,
+ colon2_token: tokens::Colon2::default(),
+ star_token: tokens::Star::default(),
+ }.into())
));
named!(view_path_list -> ViewPath, do_parse!(
path: path >>
punct!("::") >>
punct!("{") >>
- items: terminated_list!(punct!(","), path_list_item) >>
+ items: terminated_list!(map!(punct!(","), |_| tokens::Comma::default()),
+ path_list_item) >>
punct!("}") >>
- (PathList { path: path, items: items }.into())
+ (PathList {
+ path: path,
+ items: items,
+ brace_token: tokens::Brace::default(),
+ colon2_token: tokens::Colon2::default(),
+ }.into())
));
named!(view_path_list_root -> ViewPath, do_parse!(
global: option!(punct!("::")) >>
punct!("{") >>
- items: terminated_list!(punct!(","), path_list_item) >>
+ items: terminated_list!(map!(punct!(","), |_| tokens::Comma::default()),
+ path_list_item) >>
punct!("}") >>
(PathList {
path: Path {
global: global.is_some(),
- segments: Vec::new(),
+ segments: Delimited::new(),
+ leading_colon: None,
},
+ colon2_token: tokens::Colon2::default(),
+ brace_token: tokens::Brace::default(),
items: items,
}.into())
));
@@ -513,6 +602,7 @@
rename: option!(preceded!(keyword!("as"), ident)) >>
(PathListItem {
name: name,
+ as_token: rename.as_ref().map(|_| tokens::As::default()),
rename: rename,
})
));
@@ -536,6 +626,10 @@
ty: Box::new(ty),
mutbl: mutability,
expr: Box::new(value),
+ static_token: tokens::Static::default(),
+ colon_token: tokens::Colon::default(),
+ eq_token: tokens::Eq::default(),
+ semi_token: tokens::Semi::default(),
}.into(),
})
));
@@ -554,7 +648,14 @@
ident: id,
vis: vis,
attrs: attrs,
- node: ItemConst { ty: Box::new(ty), expr: Box::new(value) }.into(),
+ node: ItemConst {
+ ty: Box::new(ty),
+ expr: Box::new(value),
+ const_token: tokens::Const::default(),
+ colon_token: tokens::Colon::default(),
+ eq_token: tokens::Eq::default(),
+ semi_token: tokens::Semi::default(),
+ }.into(),
})
));
@@ -568,9 +669,10 @@
name: ident >>
generics: generics >>
punct!("(") >>
- inputs: terminated_list!(punct!(","), fn_arg) >>
+ inputs: terminated_list!(map!(punct!(","), |_| tokens::Comma::default()),
+ fn_arg) >>
punct!(")") >>
- ret: option!(preceded!(punct!("->"), ty)) >>
+ ret: fn_ret_ty >>
where_clause: where_clause >>
punct!("{") >>
inner_attrs: many0!(inner_attr) >>
@@ -586,19 +688,23 @@
},
node: ItemFn {
decl: Box::new(FnDecl {
+ dot_tokens: None,
+ fn_token: tokens::Fn::default(),
+ paren_token: tokens::Paren::default(),
inputs: inputs,
- output: ret.map(FunctionRetTy::Ty).unwrap_or(FunctionRetTy::Default),
+ output: ret,
variadic: false,
+ generics: Generics {
+ where_clause: where_clause,
+ .. generics
+ },
}),
unsafety: unsafety,
constness: constness,
abi: abi,
- generics: Generics {
- where_clause: where_clause,
- .. generics
- },
block: Box::new(Block {
stmts: stmts,
+ brace_token: tokens::Brace::default(),
}),
}.into(),
})
@@ -611,21 +717,33 @@
mutability: mutability >>
keyword!("self") >>
not!(punct!(":")) >>
- (ArgSelfRef { lifetime: lt, mutbl: mutability }.into())
+ (ArgSelfRef {
+ lifetime: lt,
+ mutbl: mutability,
+ and_token: tokens::And::default(),
+ self_token: tokens::Self_::default(),
+ }.into())
)
|
do_parse!(
mutability: mutability >>
keyword!("self") >>
not!(punct!(":")) >>
- (ArgSelf { mutbl: mutability }.into())
+ (ArgSelf {
+ mutbl: mutability,
+ self_token: tokens::Self_::default(),
+ }.into())
)
|
do_parse!(
pat: pat >>
punct!(":") >>
ty: ty >>
- (ArgCaptured { pat: pat, ty: ty }.into())
+ (ArgCaptured {
+ pat: pat,
+ ty: ty,
+ colon_token: tokens::Colon::default(),
+ }.into())
)
|
ty => { FnArg::Ignored }
@@ -657,13 +775,21 @@
attrs.extend(inner_attrs);
attrs
},
- node: ItemMod { items: Some(items) }.into(),
+ node: ItemMod {
+ mod_token: tokens::Mod::default(),
+ semi_token: None,
+ items: Some((items, tokens::Brace::default())),
+ }.into(),
},
None => Item {
ident: id,
vis: vis,
attrs: outer_attrs,
- node: ItemMod { items: None }.into(),
+ node: ItemMod {
+ items: None,
+ mod_token: tokens::Mod::default(),
+ semi_token: Some(tokens::Semi::default()),
+ }.into(),
},
})
));
@@ -676,9 +802,10 @@
punct!("}") >>
(Item {
ident: "".into(),
- vis: Visibility::Inherited,
+ vis: VisInherited {}.into(),
attrs: attrs,
node: ItemForeignMod {
+ brace_token: tokens::Brace::default(),
abi: abi,
items: items,
}.into(),
@@ -698,26 +825,35 @@
name: ident >>
generics: generics >>
punct!("(") >>
- inputs: separated_list!(punct!(","), fn_arg) >>
- trailing_comma: option!(punct!(",")) >>
- variadic: option!(cond_reduce!(trailing_comma.is_some(), punct!("..."))) >>
+ inputs: terminated_list!(map!(punct!(","), |_| tokens::Comma::default()),
+ fn_arg) >>
+ variadic: cond!(inputs.is_empty() || inputs.trailing_delim(),
+ option!(punct!("..."))) >>
punct!(")") >>
- ret: option!(preceded!(punct!("->"), ty)) >>
+ ret: fn_ret_ty >>
where_clause: where_clause >>
punct!(";") >>
(ForeignItem {
ident: name,
attrs: attrs,
+ semi_token: tokens::Semi::default(),
node: ForeignItemFn {
decl: Box::new(FnDecl {
+ fn_token: tokens::Fn::default(),
+ paren_token: tokens::Paren::default(),
inputs: inputs,
- output: ret.map(FunctionRetTy::Ty).unwrap_or(FunctionRetTy::Default),
- variadic: variadic.is_some(),
+ variadic: variadic.map(|m| m.is_some()).unwrap_or(false),
+ dot_tokens: if variadic.map(|m| m.is_some()).unwrap_or(false) {
+ Some(tokens::Dot3::default())
+ } else {
+ None
+ },
+ output: ret,
+ generics: Generics {
+ where_clause: where_clause,
+ .. generics
+ },
}),
- generics: Generics {
- where_clause: where_clause,
- .. generics
- },
}.into(),
vis: vis,
})
@@ -735,7 +871,13 @@
(ForeignItem {
ident: id,
attrs: attrs,
- node: ForeignItemStatic { ty: Box::new(ty), mutbl: mutability }.into(),
+ semi_token: tokens::Semi::default(),
+ node: ForeignItemStatic {
+ ty: Box::new(ty),
+ mutbl: mutability,
+ static_token: tokens::Static::default(),
+ colon_token: tokens::Colon::default(),
+ }.into(),
vis: vis,
})
));
@@ -755,6 +897,9 @@
vis: vis,
attrs: attrs,
node: ItemTy {
+ type_token: tokens::Type::default(),
+ eq_token: tokens::Eq::default(),
+ semi_token: tokens::Semi::default(),
ty: Box::new(ty),
generics: Generics {
where_clause: where_clause,
@@ -771,11 +916,21 @@
vis: def.vis,
attrs: def.attrs,
node: match def.body {
- Body::Enum(variants) => {
- ItemEnum { variants: variants, generics: def.generics }.into()
+ Body::Enum(data) => {
+ ItemEnum {
+ variants: data.variants,
+ brace_token: data.brace_token,
+ enum_token: data.enum_token,
+ generics: def.generics,
+ }.into()
}
- Body::Struct(variant_data) => {
- ItemStruct { data: variant_data, generics: def.generics }.into()
+ Body::Struct(data) => {
+ ItemStruct {
+ data: data.data,
+ struct_token: data.struct_token,
+ semi_token: data.semi_token,
+ generics: def.generics,
+ }.into()
}
}
}
@@ -794,7 +949,8 @@
vis: vis,
attrs: attrs,
node: ItemUnion {
- data: VariantData::Struct(fields),
+ union_token: tokens::Union::default(),
+ data: VariantData::Struct(fields.0, fields.1),
generics: Generics {
where_clause: where_clause,
.. generics
@@ -810,10 +966,11 @@
keyword!("trait") >>
id: ident >>
generics: generics >>
- bounds: opt_vec!(preceded!(
- punct!(":"),
- separated_nonempty_list!(punct!("+"), ty_param_bound)
- )) >>
+ colon: option!(punct!(":")) >>
+ bounds: cond!(colon.is_some(),
+ separated_nonempty_list!(map!(punct!("+"), |_| tokens::Add::default()),
+ ty_param_bound)
+ ) >>
where_clause: where_clause >>
punct!("{") >>
body: many0!(trait_item) >>
@@ -823,12 +980,15 @@
vis: vis,
attrs: attrs,
node: ItemTrait {
+ trait_token: tokens::Trait::default(),
+ brace_token: tokens::Brace::default(),
+ colon_token: colon.map(|_| tokens::Colon::default()),
unsafety: unsafety,
generics: Generics {
where_clause: where_clause,
.. generics
},
- supertraits: bounds,
+ supertraits: bounds.unwrap_or_default(),
items: body,
}.into(),
})
@@ -845,9 +1005,16 @@
punct!("}") >>
(Item {
ident: "".into(),
- vis: Visibility::Inherited,
+ vis: VisInherited {}.into(),
attrs: attrs,
- node: ItemDefaultImpl { unsafety: unsafety, path: path }.into(),
+ node: ItemDefaultImpl {
+ unsafety: unsafety,
+ path: path,
+ impl_token: tokens::Impl::default(),
+ for_token: tokens::For::default(),
+ dot2_token: tokens::Dot2::default(),
+ brace_token: tokens::Brace::default(),
+ }.into(),
})
));
@@ -872,7 +1039,14 @@
(TraitItem {
ident: id,
attrs: attrs,
- node: TraitItemConst { ty: ty, default: value }.into(),
+ node: TraitItemConst {
+ ty: ty,
+ const_token: tokens::Const::default(),
+ colon_token: tokens::Colon::default(),
+ eq_token: value.as_ref().map(|_| tokens::Eq::default()),
+ default: value,
+ semi_token: tokens::Semi::default(),
+ }.into(),
})
));
@@ -885,16 +1059,16 @@
name: ident >>
generics: generics >>
punct!("(") >>
- inputs: terminated_list!(punct!(","), fn_arg) >>
+ inputs: terminated_list!(map!(punct!(","), |_| tokens::Comma::default()), fn_arg) >>
punct!(")") >>
- ret: option!(preceded!(punct!("->"), ty)) >>
+ ret: fn_ret_ty >>
where_clause: where_clause >>
body: option!(delimited!(
punct!("{"),
tuple!(many0!(inner_attr), within_block),
punct!("}")
)) >>
- cond!(body.is_none(), punct!(";")) >>
+ semi: cond!(body.is_none(), punct!(";")) >>
({
let (inner_attrs, stmts) = match body {
Some((inner_attrs, stmts)) => (inner_attrs, Some(stmts)),
@@ -908,21 +1082,30 @@
attrs
},
node: TraitItemMethod {
+ semi_token: semi.map(|_| tokens::Semi::default()),
sig: MethodSig {
unsafety: unsafety,
constness: constness,
abi: abi,
decl: FnDecl {
inputs: inputs,
- output: ret.map(FunctionRetTy::Ty).unwrap_or(FunctionRetTy::Default),
+ output: ret,
variadic: false,
- },
- generics: Generics {
- where_clause: where_clause,
- .. generics
+ fn_token: tokens::Fn::default(),
+ paren_token: tokens::Paren::default(),
+ dot_tokens: None,
+ generics: Generics {
+ where_clause: where_clause,
+ .. generics
+ },
},
},
- default: stmts.map(|stmts| Block { stmts: stmts }),
+ default: stmts.map(|stmts| {
+ Block {
+ stmts: stmts,
+ brace_token: tokens::Brace::default(),
+ }
+ }),
}.into(),
}
})
@@ -932,16 +1115,24 @@
attrs: many0!(outer_attr) >>
keyword!("type") >>
id: ident >>
- bounds: opt_vec!(preceded!(
- punct!(":"),
- separated_nonempty_list!(punct!("+"), ty_param_bound)
- )) >>
+ colon: option!(punct!(":")) >>
+ bounds: cond!(colon.is_some(),
+ separated_nonempty_list!(map!(punct!("+"), |_| tokens::Add::default()),
+ ty_param_bound)
+ ) >>
default: option!(preceded!(punct!("="), ty)) >>
punct!(";") >>
(TraitItem {
ident: id,
attrs: attrs,
- node: TraitItemType { bounds: bounds, default: default }.into(),
+ node: TraitItemType {
+ type_token: tokens::Type::default(),
+ colon_token: colon.map(|_| tokens::Colon::default()),
+ bounds: bounds.unwrap_or_default(),
+ eq_token: default.as_ref().map(|_| tokens::Eq::default()),
+ semi_token: tokens::Semi::default(),
+ default: default,
+ }.into(),
})
));
@@ -950,16 +1141,14 @@
what: path >>
punct!("!") >>
body: delimited >>
- cond!(match body.delim {
- DelimToken::Paren | DelimToken::Bracket => true,
- DelimToken::Brace => false,
- }, punct!(";")) >>
+ cond!(!body.is_braced(), punct!(";")) >>
(TraitItem {
- ident: Ident::new(""),
+ ident: "".into(),
attrs: attrs,
node: TraitItemKind::Macro(Mac {
path: what,
- tts: vec![TokenTree::Delimited(body)],
+ bang_token: tokens::Bang::default(),
+ tokens: vec![body],
}),
})
));
@@ -986,9 +1175,12 @@
punct!("}") >>
(Item {
ident: "".into(),
- vis: Visibility::Inherited,
+ vis: VisInherited {}.into(),
attrs: attrs,
node: ItemImpl {
+ impl_token: tokens::Impl::default(),
+ brace_token: tokens::Brace::default(),
+ for_token: polarity_path.1.as_ref().map(|_| tokens::For::default()),
unsafety: unsafety,
polarity: polarity_path.0,
generics: Generics {
@@ -1028,7 +1220,14 @@
vis: vis,
defaultness: defaultness,
attrs: attrs,
- node: ImplItemConst { ty: ty, expr: value}.into(),
+ node: ImplItemConst {
+ ty: ty,
+ expr: value,
+ const_token: tokens::Const::default(),
+ colon_token: tokens::Colon::default(),
+ eq_token: tokens::Eq::default(),
+ semi_token: tokens::Semi::default(),
+ }.into(),
})
));
@@ -1043,9 +1242,10 @@
name: ident >>
generics: generics >>
punct!("(") >>
- inputs: terminated_list!(punct!(","), fn_arg) >>
+ inputs: terminated_list!(map!(punct!(","), |_| tokens::Comma::default()),
+ fn_arg) >>
punct!(")") >>
- ret: option!(preceded!(punct!("->"), ty)) >>
+ ret: fn_ret_ty >>
where_clause: where_clause >>
punct!("{") >>
inner_attrs: many0!(inner_attr) >>
@@ -1066,16 +1266,20 @@
constness: constness,
abi: abi,
decl: FnDecl {
+ fn_token: tokens::Fn::default(),
+ paren_token: tokens::Paren::default(),
inputs: inputs,
- output: ret.map(FunctionRetTy::Ty).unwrap_or(FunctionRetTy::Default),
+ output: ret,
variadic: false,
- },
- generics: Generics {
- where_clause: where_clause,
- .. generics
+ generics: Generics {
+ where_clause: where_clause,
+ .. generics
+ },
+ dot_tokens: None,
},
},
block: Block {
+ brace_token: tokens::Brace::default(),
stmts: stmts,
},
}.into(),
@@ -1096,7 +1300,12 @@
vis: vis,
defaultness: defaultness,
attrs: attrs,
- node: ImplItemType { ty: ty }.into(),
+ node: ImplItemType {
+ type_token: tokens::Type::default(),
+ eq_token: tokens::Eq::default(),
+ semi_token: tokens::Semi::default(),
+ ty: ty,
+ }.into(),
})
));
@@ -1105,36 +1314,34 @@
what: path >>
punct!("!") >>
body: delimited >>
- cond!(match body.delim {
- DelimToken::Paren | DelimToken::Bracket => true,
- DelimToken::Brace => false,
- }, punct!(";")) >>
+ cond!(!body.is_braced(), punct!(";")) >>
(ImplItem {
- ident: Ident::new(""),
- vis: Visibility::Inherited,
+ ident: "".into(),
+ vis: VisInherited {}.into(),
defaultness: Defaultness::Final,
attrs: attrs,
node: ImplItemKind::Macro(Mac {
path: what,
- tts: vec![TokenTree::Delimited(body)],
+ bang_token: tokens::Bang::default(),
+ tokens: vec![body],
}),
})
));
named!(impl_polarity -> ImplPolarity, alt!(
- punct!("!") => { |_| ImplPolarity::Negative }
+ punct!("!") => { |_| ImplPolarity::Negative(tokens::Bang::default()) }
|
epsilon!() => { |_| ImplPolarity::Positive }
));
named!(constness -> Constness, alt!(
- keyword!("const") => { |_| Constness::Const }
+ keyword!("const") => { |_| Constness::Const(tokens::Const::default()) }
|
epsilon!() => { |_| Constness::NotConst }
));
named!(defaultness -> Defaultness, alt!(
- keyword!("default") => { |_| Defaultness::Default }
+ keyword!("default") => { |_| Defaultness::Default(tokens::Default::default()) }
|
epsilon!() => { |_| Defaultness::Final }
));
@@ -1143,7 +1350,6 @@
#[cfg(feature = "printing")]
mod printing {
use super::*;
- use {Delimited, DelimToken, FunctionRetTy, TokenTree};
use attr::FilterAttrs;
use data::VariantData;
use quote::{Tokens, ToTokens};
@@ -1154,132 +1360,113 @@
match self.node {
ItemKind::ExternCrate(ref item) => {
self.vis.to_tokens(tokens);
- tokens.append("extern");
- tokens.append("crate");
- if let Some(ref original) = item.original {
- original.to_tokens(tokens);
- tokens.append("as");
- }
+ item.extern_token.to_tokens(tokens);
+ item.crate_token.to_tokens(tokens);
+ item.original.to_tokens(tokens);
+ item.as_token.to_tokens(tokens);
self.ident.to_tokens(tokens);
- tokens.append(";");
+ item.semi_token.to_tokens(tokens);
}
ItemKind::Use(ref item) => {
self.vis.to_tokens(tokens);
- tokens.append("use");
+ item.use_token.to_tokens(tokens);
item.path.to_tokens(tokens);
- tokens.append(";");
+ item.semi_token.to_tokens(tokens);
}
ItemKind::Static(ref item) => {
self.vis.to_tokens(tokens);
- tokens.append("static");
+ item.static_token.to_tokens(tokens);
item.mutbl.to_tokens(tokens);
self.ident.to_tokens(tokens);
- tokens.append(":");
+ item.colon_token.to_tokens(tokens);
item.ty.to_tokens(tokens);
- tokens.append("=");
+ item.eq_token.to_tokens(tokens);
item.expr.to_tokens(tokens);
- tokens.append(";");
+ item.semi_token.to_tokens(tokens);
}
ItemKind::Const(ref item) => {
self.vis.to_tokens(tokens);
- tokens.append("const");
+ item.const_token.to_tokens(tokens);
self.ident.to_tokens(tokens);
- tokens.append(":");
+ item.colon_token.to_tokens(tokens);
item.ty.to_tokens(tokens);
- tokens.append("=");
+ item.eq_token.to_tokens(tokens);
item.expr.to_tokens(tokens);
- tokens.append(";");
+ item.semi_token.to_tokens(tokens);
}
ItemKind::Fn(ref item) => {
self.vis.to_tokens(tokens);
item.constness.to_tokens(tokens);
item.unsafety.to_tokens(tokens);
item.abi.to_tokens(tokens);
- tokens.append("fn");
- self.ident.to_tokens(tokens);
- item.generics.to_tokens(tokens);
- tokens.append("(");
- tokens.append_separated(&item.decl.inputs, ",");
- tokens.append(")");
- if let FunctionRetTy::Ty(ref ty) = item.decl.output {
- tokens.append("->");
- ty.to_tokens(tokens);
- }
- item.generics.where_clause.to_tokens(tokens);
- tokens.append("{");
- tokens.append_all(self.attrs.inner());
- tokens.append_all(&item.block.stmts);
- tokens.append("}");
+ NamedDecl(&item.decl, &self.ident).to_tokens(tokens);
+ item.block.brace_token.surround(tokens, |tokens| {
+ tokens.append_all(self.attrs.inner());
+ tokens.append_all(&item.block.stmts);
+ });
}
ItemKind::Mod(ref item) => {
self.vis.to_tokens(tokens);
- tokens.append("mod");
+ item.mod_token.to_tokens(tokens);
self.ident.to_tokens(tokens);
- match item.items {
- Some(ref items) => {
- tokens.append("{");
+ if let Some((ref items, ref brace)) = item.items {
+ brace.surround(tokens, |tokens| {
tokens.append_all(self.attrs.inner());
tokens.append_all(items);
- tokens.append("}");
- }
- None => tokens.append(";"),
+ });
}
+ item.semi_token.to_tokens(tokens);
}
- ItemKind::ForeignMod(ref foreign_mod) => {
+ ItemKind::ForeignMod(ref item) => {
self.vis.to_tokens(tokens);
- foreign_mod.abi.to_tokens(tokens);
- tokens.append("{");
- tokens.append_all(&foreign_mod.items);
- tokens.append("}");
+ item.abi.to_tokens(tokens);
+ item.brace_token.surround(tokens, |tokens| {
+ tokens.append_all(&item.items);
+ });
}
ItemKind::Ty(ref item) => {
self.vis.to_tokens(tokens);
- tokens.append("type");
+ item.type_token.to_tokens(tokens);
self.ident.to_tokens(tokens);
item.generics.to_tokens(tokens);
item.generics.where_clause.to_tokens(tokens);
- tokens.append("=");
+ item.eq_token.to_tokens(tokens);
item.ty.to_tokens(tokens);
- tokens.append(";");
+ item.semi_token.to_tokens(tokens);
}
ItemKind::Enum(ref item) => {
self.vis.to_tokens(tokens);
- tokens.append("enum");
+ item.enum_token.to_tokens(tokens);
self.ident.to_tokens(tokens);
item.generics.to_tokens(tokens);
item.generics.where_clause.to_tokens(tokens);
- tokens.append("{");
- for variant in &item.variants {
- variant.to_tokens(tokens);
- tokens.append(",");
- }
- tokens.append("}");
+ item.brace_token.surround(tokens, |tokens| {
+ item.variants.to_tokens(tokens);
+ });
}
ItemKind::Struct(ref item) => {
self.vis.to_tokens(tokens);
- tokens.append("struct");
+ item.struct_token.to_tokens(tokens);
self.ident.to_tokens(tokens);
item.generics.to_tokens(tokens);
match item.data {
- VariantData::Struct(_) => {
+ VariantData::Struct(..) => {
item.generics.where_clause.to_tokens(tokens);
item.data.to_tokens(tokens);
- // no semicolon
}
- VariantData::Tuple(_) => {
+ VariantData::Tuple(..) => {
item.data.to_tokens(tokens);
item.generics.where_clause.to_tokens(tokens);
- tokens.append(";");
}
VariantData::Unit => {
item.generics.where_clause.to_tokens(tokens);
- tokens.append(";");
}
}
+ item.semi_token.to_tokens(tokens);
}
ItemKind::Union(ref item) => {
self.vis.to_tokens(tokens);
- tokens.append("union");
+ item.union_token.to_tokens(tokens);
self.ident.to_tokens(tokens);
item.generics.to_tokens(tokens);
item.generics.where_clause.to_tokens(tokens);
@@ -1288,54 +1475,44 @@
ItemKind::Trait(ref item) => {
self.vis.to_tokens(tokens);
item.unsafety.to_tokens(tokens);
- tokens.append("trait");
+ item.trait_token.to_tokens(tokens);
self.ident.to_tokens(tokens);
item.generics.to_tokens(tokens);
- if !item.supertraits.is_empty() {
- tokens.append(":");
- tokens.append_separated(&item.supertraits, "+");
- }
+ item.colon_token.to_tokens(tokens);
+ item.supertraits.to_tokens(tokens);
item.generics.where_clause.to_tokens(tokens);
- tokens.append("{");
- tokens.append_all(&item.items);
- tokens.append("}");
+ item.brace_token.surround(tokens, |tokens| {
+ tokens.append_all(&item.items);
+ });
}
ItemKind::DefaultImpl(ref item) => {
item.unsafety.to_tokens(tokens);
- tokens.append("impl");
+ item.impl_token.to_tokens(tokens);
item.path.to_tokens(tokens);
- tokens.append("for");
- tokens.append("..");
- tokens.append("{");
- tokens.append("}");
+ item.for_token.to_tokens(tokens);
+ item.dot2_token.to_tokens(tokens);
+ item.brace_token.surround(tokens, |_tokens| {});
}
ItemKind::Impl(ref item) => {
item.unsafety.to_tokens(tokens);
- tokens.append("impl");
+ item.impl_token.to_tokens(tokens);
item.generics.to_tokens(tokens);
- if let Some(ref path) = item.trait_ {
- item.polarity.to_tokens(tokens);
- path.to_tokens(tokens);
- tokens.append("for");
- }
+ item.polarity.to_tokens(tokens);
+ item.trait_.to_tokens(tokens);
+ item.for_token.to_tokens(tokens);
item.self_ty.to_tokens(tokens);
item.generics.where_clause.to_tokens(tokens);
- tokens.append("{");
- tokens.append_all(&item.items);
- tokens.append("}");
+ item.brace_token.surround(tokens, |tokens| {
+ tokens.append_all(&item.items);
+ });
}
ItemKind::Mac(ref mac) => {
mac.path.to_tokens(tokens);
- tokens.append("!");
+ mac.bang_token.to_tokens(tokens);
self.ident.to_tokens(tokens);
- for tt in &mac.tts {
- tt.to_tokens(tokens);
- }
- match mac.tts.last() {
- Some(&TokenTree::Delimited(Delimited { delim: DelimToken::Brace, .. })) => {
- // no semicolon
- }
- _ => tokens.append(";"),
+ tokens.append_all(&mac.tokens);
+ if !mac.is_braced() {
+ tokens::Semi::default().to_tokens(tokens);
}
}
}
@@ -1345,40 +1522,34 @@
impl ToTokens for PathSimple {
fn to_tokens(&self, tokens: &mut Tokens) {
self.path.to_tokens(tokens);
- if let Some(ref rename) = self.rename {
- tokens.append("as");
- rename.to_tokens(tokens);
- }
+ self.as_token.to_tokens(tokens);
+ self.rename.to_tokens(tokens);
}
}
impl ToTokens for PathGlob {
fn to_tokens(&self, tokens: &mut Tokens) {
self.path.to_tokens(tokens);
- tokens.append("::");
- tokens.append("*");
+ self.colon2_token.to_tokens(tokens);
+ self.star_token.to_tokens(tokens);
}
}
impl ToTokens for PathList {
fn to_tokens(&self, tokens: &mut Tokens) {
self.path.to_tokens(tokens);
- if self.path.global || !self.path.segments.is_empty() {
- tokens.append("::");
- }
- tokens.append("{");
- tokens.append_separated(&self.items, ",");
- tokens.append("}");
+ self.colon2_token.to_tokens(tokens);
+ self.brace_token.surround(tokens, |tokens| {
+ self.items.to_tokens(tokens);
+ });
}
}
impl ToTokens for PathListItem {
fn to_tokens(&self, tokens: &mut Tokens) {
self.name.to_tokens(tokens);
- if let Some(ref rename) = self.rename {
- tokens.append("as");
- rename.to_tokens(tokens);
- }
+ self.as_token.to_tokens(tokens);
+ self.rename.to_tokens(tokens);
}
}
@@ -1387,61 +1558,41 @@
tokens.append_all(self.attrs.outer());
match self.node {
TraitItemKind::Const(ref item) => {
- tokens.append("const");
+ item.const_token.to_tokens(tokens);
self.ident.to_tokens(tokens);
- tokens.append(":");
+ item.colon_token.to_tokens(tokens);
item.ty.to_tokens(tokens);
- if let Some(ref expr) = item.default {
- tokens.append("=");
- expr.to_tokens(tokens);
- }
- tokens.append(";");
+ item.eq_token.to_tokens(tokens);
+ item.default.to_tokens(tokens);
+ item.semi_token.to_tokens(tokens);
}
TraitItemKind::Method(ref item) => {
- item.sig.constness.to_tokens(tokens);
- item.sig.unsafety.to_tokens(tokens);
- item.sig.abi.to_tokens(tokens);
- tokens.append("fn");
- self.ident.to_tokens(tokens);
- item.sig.generics.to_tokens(tokens);
- tokens.append("(");
- tokens.append_separated(&item.sig.decl.inputs, ",");
- tokens.append(")");
- if let FunctionRetTy::Ty(ref ty) = item.sig.decl.output {
- tokens.append("->");
- ty.to_tokens(tokens);
- }
- item.sig.generics.where_clause.to_tokens(tokens);
+ NamedMethod(&item.sig, &self.ident).to_tokens(tokens);
match item.default {
Some(ref block) => {
- tokens.append("{");
- tokens.append_all(self.attrs.inner());
- tokens.append_all(&block.stmts);
- tokens.append("}");
+ block.brace_token.surround(tokens, |tokens| {
+ tokens.append_all(self.attrs.inner());
+ tokens.append_all(&block.stmts);
+ });
}
- None => tokens.append(";"),
+ None => {
+ item.semi_token.to_tokens(tokens);
+ }
}
}
TraitItemKind::Type(ref item) => {
- tokens.append("type");
+ item.type_token.to_tokens(tokens);
self.ident.to_tokens(tokens);
- if !item.bounds.is_empty() {
- tokens.append(":");
- tokens.append_separated(&item.bounds, "+");
- }
- if let Some(ref default) = item.default {
- tokens.append("=");
- default.to_tokens(tokens);
- }
- tokens.append(";");
+ item.colon_token.to_tokens(tokens);
+ item.bounds.to_tokens(tokens);
+ item.eq_token.to_tokens(tokens);
+ item.default.to_tokens(tokens);
+ item.semi_token.to_tokens(tokens);
}
TraitItemKind::Macro(ref mac) => {
mac.to_tokens(tokens);
- match mac.tts.last() {
- Some(&TokenTree::Delimited(Delimited { delim: DelimToken::Brace, .. })) => {
- // no semicolon
- }
- _ => tokens.append(";"),
+ if !mac.is_braced() {
+ tokens::Semi::default().to_tokens(tokens);
}
}
}
@@ -1451,56 +1602,36 @@
impl ToTokens for ImplItem {
fn to_tokens(&self, tokens: &mut Tokens) {
tokens.append_all(self.attrs.outer());
+ self.vis.to_tokens(tokens);
+ self.defaultness.to_tokens(tokens);
match self.node {
ImplItemKind::Const(ref item) => {
- self.vis.to_tokens(tokens);
- self.defaultness.to_tokens(tokens);
- tokens.append("const");
+ item.const_token.to_tokens(tokens);
self.ident.to_tokens(tokens);
- tokens.append(":");
+ item.colon_token.to_tokens(tokens);
item.ty.to_tokens(tokens);
- tokens.append("=");
+ item.eq_token.to_tokens(tokens);
item.expr.to_tokens(tokens);
- tokens.append(";");
+ item.semi_token.to_tokens(tokens);
}
ImplItemKind::Method(ref item) => {
- self.vis.to_tokens(tokens);
- self.defaultness.to_tokens(tokens);
- item.sig.constness.to_tokens(tokens);
- item.sig.unsafety.to_tokens(tokens);
- item.sig.abi.to_tokens(tokens);
- tokens.append("fn");
- self.ident.to_tokens(tokens);
- item.sig.generics.to_tokens(tokens);
- tokens.append("(");
- tokens.append_separated(&item.sig.decl.inputs, ",");
- tokens.append(")");
- if let FunctionRetTy::Ty(ref ty) = item.sig.decl.output {
- tokens.append("->");
- ty.to_tokens(tokens);
- }
- item.sig.generics.where_clause.to_tokens(tokens);
- tokens.append("{");
- tokens.append_all(self.attrs.inner());
- tokens.append_all(&item.block.stmts);
- tokens.append("}");
+ NamedMethod(&item.sig, &self.ident).to_tokens(tokens);
+ item.block.brace_token.surround(tokens, |tokens| {
+ tokens.append_all(self.attrs.inner());
+ tokens.append_all(&item.block.stmts);
+ });
}
ImplItemKind::Type(ref item) => {
- self.vis.to_tokens(tokens);
- self.defaultness.to_tokens(tokens);
- tokens.append("type");
+ item.type_token.to_tokens(tokens);
self.ident.to_tokens(tokens);
- tokens.append("=");
+ item.eq_token.to_tokens(tokens);
item.ty.to_tokens(tokens);
- tokens.append(";");
+ item.semi_token.to_tokens(tokens);
}
ImplItemKind::Macro(ref mac) => {
mac.to_tokens(tokens);
- match mac.tts.last() {
- Some(&TokenTree::Delimited(Delimited { delim: DelimToken::Brace, .. })) => {
- // no semicolon
- }
- _ => tokens.append(";"),
+ if !mac.is_braced() {
+ tokens::Semi::default().to_tokens(tokens);
}
}
}
@@ -1510,61 +1641,70 @@
impl ToTokens for ForeignItem {
fn to_tokens(&self, tokens: &mut Tokens) {
tokens.append_all(self.attrs.outer());
+ self.vis.to_tokens(tokens);
match self.node {
ForeignItemKind::Fn(ref item) => {
- self.vis.to_tokens(tokens);
- tokens.append("fn");
- self.ident.to_tokens(tokens);
- item.generics.to_tokens(tokens);
- tokens.append("(");
- tokens.append_separated(&item.decl.inputs, ",");
- if item.decl.variadic {
- if !item.decl.inputs.is_empty() {
- tokens.append(",");
- }
- tokens.append("...");
- }
- tokens.append(")");
- if let FunctionRetTy::Ty(ref ty) = item.decl.output {
- tokens.append("->");
- ty.to_tokens(tokens);
- }
- item.generics.where_clause.to_tokens(tokens);
- tokens.append(";");
+ NamedDecl(&item.decl, &self.ident).to_tokens(tokens)
}
ForeignItemKind::Static(ref item) => {
- self.vis.to_tokens(tokens);
- tokens.append("static");
+ item.static_token.to_tokens(tokens);
item.mutbl.to_tokens(tokens);
self.ident.to_tokens(tokens);
- tokens.append(":");
+ item.colon_token.to_tokens(tokens);
item.ty.to_tokens(tokens);
- tokens.append(";");
}
}
+ self.semi_token.to_tokens(tokens);
+ }
+ }
+
+ struct NamedMethod<'a>(&'a MethodSig, &'a Ident);
+
+ impl<'a> ToTokens for NamedMethod<'a> {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ self.0.constness.to_tokens(tokens);
+ self.0.unsafety.to_tokens(tokens);
+ self.0.abi.to_tokens(tokens);
+ NamedDecl(&self.0.decl, self.1).to_tokens(tokens);
+ }
+ }
+
+ struct NamedDecl<'a>(&'a FnDecl, &'a Ident);
+
+ impl<'a> ToTokens for NamedDecl<'a> {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ self.0.fn_token.to_tokens(tokens);
+ self.1.to_tokens(tokens);
+ self.0.generics.to_tokens(tokens);
+ self.0.paren_token.surround(tokens, |tokens| {
+ self.0.inputs.to_tokens(tokens);
+ self.0.dot_tokens.to_tokens(tokens);
+ });
+ self.0.output.to_tokens(tokens);
+ self.0.generics.where_clause.to_tokens(tokens);
}
}
impl ToTokens for ArgSelfRef {
fn to_tokens(&self, tokens: &mut Tokens) {
- tokens.append("&");
+ self.and_token.to_tokens(tokens);
self.lifetime.to_tokens(tokens);
self.mutbl.to_tokens(tokens);
- tokens.append("self");
+ self.self_token.to_tokens(tokens);
}
}
impl ToTokens for ArgSelf {
fn to_tokens(&self, tokens: &mut Tokens) {
self.mutbl.to_tokens(tokens);
- tokens.append("self");
+ self.self_token.to_tokens(tokens);
}
}
impl ToTokens for ArgCaptured {
fn to_tokens(&self, tokens: &mut Tokens) {
self.pat.to_tokens(tokens);
- tokens.append(":");
+ self.colon_token.to_tokens(tokens);
self.ty.to_tokens(tokens);
}
}
@@ -1572,7 +1712,7 @@
impl ToTokens for Constness {
fn to_tokens(&self, tokens: &mut Tokens) {
match *self {
- Constness::Const => tokens.append("const"),
+ Constness::Const(ref t) => t.to_tokens(tokens),
Constness::NotConst => {
// nothing
}
@@ -1583,7 +1723,7 @@
impl ToTokens for Defaultness {
fn to_tokens(&self, tokens: &mut Tokens) {
match *self {
- Defaultness::Default => tokens.append("default"),
+ Defaultness::Default(ref t) => t.to_tokens(tokens),
Defaultness::Final => {
// nothing
}
@@ -1594,7 +1734,7 @@
impl ToTokens for ImplPolarity {
fn to_tokens(&self, tokens: &mut Tokens) {
match *self {
- ImplPolarity::Negative => tokens.append("!"),
+ ImplPolarity::Negative(ref t) => t.to_tokens(tokens),
ImplPolarity::Positive => {
// nothing
}
diff --git a/src/krate.rs b/src/krate.rs
index 113e142..1d83d9b 100644
--- a/src/krate.rs
+++ b/src/krate.rs
@@ -44,15 +44,12 @@
impl ToTokens for Crate {
fn to_tokens(&self, tokens: &mut Tokens) {
- if let Some(ref shebang) = self.shebang {
- tokens.append(&format!("{}\n", shebang));
- }
- for attr in self.attrs.inner() {
- attr.to_tokens(tokens);
- }
- for item in &self.items {
- item.to_tokens(tokens);
- }
+ // TODO: how to handle shebang?
+ // if let Some(ref shebang) = self.shebang {
+ // tokens.append(&format!("{}\n", shebang));
+ // }
+ tokens.append_all(self.attrs.inner());
+ tokens.append_all(&self.items);
}
}
}
diff --git a/src/lib.rs b/src/lib.rs
index f30683f..b422c6c 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -2,14 +2,15 @@
#![cfg_attr(feature = "cargo-clippy", allow(large_enum_variant))]
+extern crate proc_macro2;
+
#[cfg(feature = "printing")]
extern crate quote;
#[cfg(feature = "parsing")]
extern crate unicode_xid;
-#[cfg(feature = "parsing")]
-#[macro_use]
+#[cfg_attr(feature = "parsing", macro_use)]
extern crate synom;
#[cfg(feature = "aster")]
@@ -27,7 +28,8 @@
ConstIndex, ConstParen};
mod data;
-pub use data::{Field, Variant, VariantData, Visibility};
+pub use data::{Field, Variant, VariantData, Visibility, VisRestricted, VisCrate,
+ VisPublic, VisInherited};
#[cfg(feature = "parsing")]
mod escape;
@@ -42,12 +44,14 @@
ExprForLoop, ExprLoop, ExprMatch, ExprClosure, ExprBlock,
ExprAssign, ExprAssignOp, ExprField, ExprTupField, ExprIndex,
ExprRange, ExprPath, ExprAddrOf, ExprBreak, ExprContinue,
- ExprRet, ExprStruct, ExprRepeat, ExprParen, ExprTry, ExprCatch};
+ ExprRet, ExprStruct, ExprRepeat, ExprParen, ExprTry, ExprCatch,
+ PatIdent, PatWild, PatStruct, PatTuple, PatTupleStruct, PatPath,
+ PatBox, PatRef, PatLit, PatRange, PatSlice};
mod generics;
pub use generics::{Generics, Lifetime, LifetimeDef, TraitBoundModifier, TyParam, TyParamBound,
WhereBoundPredicate, WhereClause, WhereEqPredicate, WherePredicate,
- WhereRegionPredicate};
+ WhereRegionPredicate, BoundLifetimes};
#[cfg(feature = "printing")]
pub use generics::{ImplGenerics, Turbofish, TyGenerics};
@@ -73,15 +77,13 @@
pub use krate::Crate;
mod lit;
-pub use lit::{FloatTy, IntTy, Lit, StrStyle};
-#[cfg(feature = "parsing")]
-pub use lit::{ByteStrLit, FloatLit, IntLit, StrLit};
+pub use lit::{Lit, LitKind};
mod mac;
-pub use mac::{BinOpToken, DelimToken, Delimited, Mac, Token, TokenTree};
+pub use mac::{Mac, TokenTree};
mod derive;
-pub use derive::{Body, DeriveInput};
+pub use derive::{Body, DeriveInput, BodyEnum, BodyStruct};
// Deprecated. Use `DeriveInput` instead.
#[doc(hidden)]
pub type MacroInput = DeriveInput;
@@ -95,6 +97,14 @@
PolyTraitRef, QSelf, Ty, TypeBinding, Unsafety, TySlice, TyArray,
TyPtr, TyRptr, TyBareFn, TyNever, TyTup, TyPath, TyTraitObject,
TyImplTrait, TyParen, TyInfer};
+#[cfg(feature = "printing")]
+pub use ty::PathTokens;
+
+mod span;
+pub use span::Span;
+
+pub mod tokens;
+pub use synom::delimited;
#[cfg(feature = "visit")]
pub mod visit;
diff --git a/src/lit.rs b/src/lit.rs
index 72a2f43..9c9f274 100644
--- a/src/lit.rs
+++ b/src/lit.rs
@@ -1,170 +1,100 @@
-ast_enum! {
- /// Literal kind.
- ///
- /// E.g. `"foo"`, `42`, `12.34` or `bool`
- #[cfg_attr(not(feature = "clone-impls"), derive(Clone))]
- pub enum Lit {
- /// A string literal (`"foo"`)
- Str(String, StrStyle),
- /// A byte string (`b"foo"`)
- ByteStr(Vec<u8>, StrStyle),
- /// A byte char (`b'f'`)
- Byte(u8),
- /// A character literal (`'a'`)
- Char(char),
- /// An integer literal (`1`)
- Int(u64, IntTy),
- /// A float literal (`1f64` or `1E10f64` or `1.0E10`)
- Float(String, FloatTy),
- /// A boolean literal
- Bool(bool),
+use std::fmt;
+use std::hash::{Hash, Hasher};
+
+use proc_macro2::{self, Literal, TokenKind};
+
+use {Span, TokenTree};
+
+#[derive(Clone)]
+pub struct Lit {
+ pub value: LitKind,
+ pub span: Span,
+}
+
+#[derive(Clone)]
+pub enum LitKind {
+ Bool(bool),
+ Other(Literal),
+}
+
+impl Lit {
+ pub fn into_token_tree(self) -> TokenTree {
+ let kind = match self.value {
+ LitKind::Bool(true) => TokenKind::Word("true".into()),
+ LitKind::Bool(false) => TokenKind::Word("false".into()),
+ LitKind::Other(l) => TokenKind::Literal(l),
+ };
+ TokenTree(proc_macro2::TokenTree {
+ span: self.span.0,
+ kind: kind,
+ })
}
}
-ast_enum! {
- #[cfg_attr(not(feature = "clone-impls"), derive(Clone))]
- pub enum StrStyle {
- /// A regular string, like `"foo"`
- Cooked,
- /// A raw string, like `r##"foo"##`
- ///
- /// The uint is the number of `#` symbols used
- Raw(usize),
+impl fmt::Display for Lit {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ fmt::Display::fmt(&self.value, f)
}
}
-impl From<String> for Lit {
- fn from(input: String) -> Lit {
- Lit::Str(input, StrStyle::Cooked)
+impl fmt::Debug for Lit {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ fmt::Display::fmt(&self.value, f)
}
}
-impl<'a> From<&'a str> for Lit {
- fn from(input: &str) -> Lit {
- Lit::Str(input.into(), StrStyle::Cooked)
+impl PartialEq for Lit {
+ fn eq(&self, other: &Lit) -> bool {
+ self.value == other.value
}
}
-impl From<Vec<u8>> for Lit {
- fn from(input: Vec<u8>) -> Lit {
- Lit::ByteStr(input, StrStyle::Cooked)
+impl Eq for Lit {}
+
+impl Hash for Lit {
+ fn hash<H: Hasher>(&self, hasher: &mut H) {
+ self.value.hash(hasher)
}
}
-impl<'a> From<&'a [u8]> for Lit {
- fn from(input: &[u8]) -> Lit {
- Lit::ByteStr(input.into(), StrStyle::Cooked)
+impl fmt::Display for LitKind {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match *self {
+ LitKind::Bool(b) => b.fmt(f),
+ LitKind::Other(ref l) => l.fmt(f),
+ }
}
}
-impl From<char> for Lit {
- fn from(input: char) -> Lit {
- Lit::Char(input)
+impl fmt::Debug for LitKind {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match *self {
+ LitKind::Bool(b) => b.fmt(f),
+ LitKind::Other(ref l) => fmt::Display::fmt(l, f),
+ }
}
}
-impl From<bool> for Lit {
- fn from(input: bool) -> Lit {
- Lit::Bool(input)
- }
-}
-
-ast_enum! {
- #[derive(Copy)]
- #[cfg_attr(not(feature = "clone-impls"), derive(Clone))]
- pub enum IntTy {
- Isize,
- I8,
- I16,
- I32,
- I64,
- Usize,
- U8,
- U16,
- U32,
- U64,
- Unsuffixed,
- }
-}
-
-ast_enum! {
- #[derive(Copy)]
- #[cfg_attr(not(feature = "clone-impls"), derive(Clone))]
- pub enum FloatTy {
- F32,
- F64,
- Unsuffixed,
- }
-}
-
-macro_rules! impl_from_for_lit {
- (Int, [$($rust_type:ty => $syn_type:expr),+]) => {
- $(
- impl From<$rust_type> for Lit {
- fn from(input: $rust_type) -> Lit {
- Lit::Int(input as u64, $syn_type)
- }
+impl PartialEq for LitKind {
+ fn eq(&self, other: &LitKind) -> bool {
+ match (self, other) {
+ (&LitKind::Bool(b1), &LitKind::Bool(b2)) => b1 == b2,
+ (&LitKind::Other(ref l1), &LitKind::Other(ref l2)) => {
+ l1.to_string() == l2.to_string()
}
- )+
- };
- (Float, [$($rust_type:ty => $syn_type:expr),+]) => {
- $(
- impl From<$rust_type> for Lit {
- fn from(input: $rust_type) -> Lit {
- Lit::Float(format!("{}", input), $syn_type)
- }
- }
- )+
- };
-}
-
-impl_from_for_lit! {Int, [
- isize => IntTy::Isize,
- i8 => IntTy::I8,
- i16 => IntTy::I16,
- i32 => IntTy::I32,
- i64 => IntTy::I64,
- usize => IntTy::Usize,
- u8 => IntTy::U8,
- u16 => IntTy::U16,
- u32 => IntTy::U32,
- u64 => IntTy::U64
-]}
-
-impl_from_for_lit! {Float, [
- f32 => FloatTy::F32,
- f64 => FloatTy::F64
-]}
-
-#[cfg(feature = "parsing")]
-ast_struct! {
- pub struct StrLit {
- pub value: String,
- pub style: StrStyle,
+ _ => false,
+ }
}
}
-#[cfg(feature = "parsing")]
-ast_struct! {
- pub struct ByteStrLit {
- pub value: Vec<u8>,
- pub style: StrStyle,
- }
-}
+impl Eq for LitKind {}
-#[cfg(feature = "parsing")]
-ast_struct! {
- pub struct IntLit {
- pub value: u64,
- pub suffix: IntTy,
- }
-}
-
-#[cfg(feature = "parsing")]
-ast_struct! {
- pub struct FloatLit {
- pub value: String,
- pub suffix: FloatTy,
+impl Hash for LitKind {
+ fn hash<H: Hasher>(&self, hasher: &mut H) {
+ match *self {
+ LitKind::Bool(b) => (0u8, b).hash(hasher),
+ LitKind::Other(ref l) => (1u8, l.to_string()).hash(hasher),
+ }
}
}
@@ -172,33 +102,41 @@
pub mod parsing {
use super::*;
use escape::{cooked_byte, cooked_byte_string, cooked_char, cooked_string, raw_string};
- use synom::space::skip_whitespace;
+ use proc_macro2::Literal;
use synom::IResult;
+ use synom::space::skip_whitespace;
use unicode_xid::UnicodeXID;
+ fn l<T: Into<Literal>>(t: T) -> Lit {
+ Lit {
+ value: LitKind::Other(t.into()),
+ span: Default::default(),
+ }
+ }
+
named!(pub lit -> Lit, alt!(
- string => { |StrLit { value, style }| Lit::Str(value, style) }
+ string
|
- byte_string => { |ByteStrLit { value, style }| Lit::ByteStr(value, style) }
+ byte_string
|
- byte => { |b| Lit::Byte(b) }
+ byte
|
- character => { |ch| Lit::Char(ch) }
+ character
|
- float => { |FloatLit { value, suffix }| Lit::Float(value, suffix) } // must be before int
+ float
|
- int => { |IntLit { value, suffix }| Lit::Int(value, suffix) }
+ int
|
- boolean => { |value| Lit::Bool(value) }
+ boolean
));
- named!(pub string -> StrLit, alt!(
- quoted_string => { |s| StrLit { value: s, style: StrStyle::Cooked } }
+ named!(pub string -> Lit, alt!(
+ quoted_string => { |s: String| l(&s[..]) }
|
preceded!(
punct!("r"),
raw_string
- ) => { |(s, n)| StrLit { value: s, style: StrStyle::Raw(n) }}
+ ) => { |(s, n): (String, _)| l(Literal::raw_string(&s[..], n)) }
));
named!(pub quoted_string -> String, delimited!(
@@ -207,78 +145,84 @@
tag!("\"")
));
- named!(pub byte_string -> ByteStrLit, alt!(
+ named!(pub byte_string -> Lit, alt!(
delimited!(
punct!("b\""),
cooked_byte_string,
tag!("\"")
- ) => { |vec| ByteStrLit { value: vec, style: StrStyle::Cooked } }
+ ) => { |vec: Vec<u8>| l(Literal::byte_string(&vec)) }
|
preceded!(
punct!("br"),
raw_string
- ) => { |(s, n): (String, _)| ByteStrLit { value: s.into_bytes(), style: StrStyle::Raw(n) } }
+ ) => { |(s, n): (String, _)| l(Literal::raw_byte_string(&s, n)) }
));
- named!(pub byte -> u8, do_parse!(
+ named!(pub byte -> Lit, do_parse!(
punct!("b") >>
tag!("'") >>
b: cooked_byte >>
tag!("'") >>
- (b)
+ (l(Literal::byte_char(b)))
));
- named!(pub character -> char, do_parse!(
+ named!(pub character -> Lit, do_parse!(
punct!("'") >>
ch: cooked_char >>
tag!("'") >>
- (ch)
+ (l(ch))
));
- named!(pub float -> FloatLit, do_parse!(
+ named!(pub float -> Lit, do_parse!(
value: float_string >>
suffix: alt!(
- tag!("f32") => { |_| FloatTy::F32 }
+ tag!("f32")
|
- tag!("f64") => { |_| FloatTy::F64 }
+ tag!("f64")
|
- epsilon!() => { |_| FloatTy::Unsuffixed }
+ epsilon!() => { |_| "" }
) >>
- (FloatLit { value: value, suffix: suffix })
+ (l(Literal::float(&format!("{}{}", value, suffix))))
));
- named!(pub int -> IntLit, do_parse!(
+ named!(pub int -> Lit, do_parse!(
value: digits >>
suffix: alt!(
- tag!("isize") => { |_| IntTy::Isize }
+ tag!("isize")
|
- tag!("i8") => { |_| IntTy::I8 }
+ tag!("i8")
|
- tag!("i16") => { |_| IntTy::I16 }
+ tag!("i16")
|
- tag!("i32") => { |_| IntTy::I32 }
+ tag!("i32")
|
- tag!("i64") => { |_| IntTy::I64 }
+ tag!("i64")
|
- tag!("usize") => { |_| IntTy::Usize }
+ tag!("usize")
|
- tag!("u8") => { |_| IntTy::U8 }
+ tag!("u8")
|
- tag!("u16") => { |_| IntTy::U16 }
+ tag!("u16")
|
- tag!("u32") => { |_| IntTy::U32 }
+ tag!("u32")
|
- tag!("u64") => { |_| IntTy::U64 }
+ tag!("u64")
|
- epsilon!() => { |_| IntTy::Unsuffixed }
+ epsilon!() => { |_| "" }
) >>
- (IntLit { value: value, suffix: suffix })
+ (l(Literal::integer(&format!("{}{}", value, suffix))))
));
- named!(pub boolean -> bool, alt!(
- keyword!("true") => { |_| true }
+ named!(pub boolean -> Lit, alt!(
+ keyword!("true") => { |_| Lit {
+ span: Span::default(),
+ value: LitKind::Bool(true),
+ } }
|
- keyword!("false") => { |_| false }
+ keyword!("false") => { |_| Lit {
+ span: Span::default(),
+ value: LitKind::Bool(false),
+ } }
));
fn float_string(mut input: &str) -> IResult<&str, String> {
@@ -358,26 +302,23 @@
IResult::Done(&input[len..], input[..len].replace("_", ""))
}
- pub fn digits(mut input: &str) -> IResult<&str, u64> {
+ pub fn digits(mut input: &str) -> IResult<&str, &str> {
input = skip_whitespace(input);
let base = if input.starts_with("0x") {
- input = &input[2..];
16
} else if input.starts_with("0o") {
- input = &input[2..];
8
} else if input.starts_with("0b") {
- input = &input[2..];
2
} else {
10
};
let mut value = 0u64;
- let mut len = 0;
+ let mut len = if base == 10 {0} else {2};
let mut empty = true;
- for b in input.bytes() {
+ for b in input[len..].bytes() {
let digit = match b {
b'0'...b'9' => (b - b'0') as u64,
b'a'...b'f' => 10 + (b - b'a') as u64,
@@ -408,7 +349,7 @@
if empty {
IResult::Error
} else {
- IResult::Done(&input[len..], value)
+ IResult::Done(&input[len..], &input[..len])
}
}
}
@@ -417,82 +358,20 @@
mod printing {
use super::*;
use quote::{Tokens, ToTokens};
- use std::{ascii, iter};
- use std::fmt::{self, Display};
- use std::str;
+
+ use proc_macro2::{TokenTree, TokenKind};
impl ToTokens for Lit {
fn to_tokens(&self, tokens: &mut Tokens) {
- match *self {
- Lit::Str(ref s, StrStyle::Cooked) => s.to_tokens(tokens),
- Lit::Str(ref s, StrStyle::Raw(n)) => {
- tokens.append(&format!("r{delim}\"{string}\"{delim}",
- delim = iter::repeat("#").take(n).collect::<String>(),
- string = s));
- }
- Lit::ByteStr(ref v, StrStyle::Cooked) => {
- let mut escaped = "b\"".to_string();
- for &ch in v.iter() {
- match ch {
- 0 => escaped.push_str(r"\0"),
- b'\'' => escaped.push('\''),
- _ => escaped.extend(ascii::escape_default(ch).map(|c| c as char)),
- }
- }
- escaped.push('"');
- tokens.append(&escaped);
- }
- Lit::ByteStr(ref vec, StrStyle::Raw(n)) => {
- tokens.append(&format!("br{delim}\"{string}\"{delim}",
- delim = iter::repeat("#").take(n).collect::<String>(),
- string = str::from_utf8(vec).unwrap()));
- }
- Lit::Byte(b) => {
- match b {
- 0 => tokens.append(r"b'\0'"),
- b'\"' => tokens.append("b'\"'"),
- _ => {
- let mut escaped = "b'".to_string();
- escaped.extend(ascii::escape_default(b).map(|c| c as char));
- escaped.push('\'');
- tokens.append(&escaped);
- }
- }
- }
- Lit::Char(ch) => ch.to_tokens(tokens),
- Lit::Int(value, ty) => tokens.append(&format!("{}{}", value, ty)),
- Lit::Float(ref value, ty) => tokens.append(&format!("{}{}", value, ty)),
- Lit::Bool(true) => tokens.append("true"),
- Lit::Bool(false) => tokens.append("false"),
- }
- }
- }
-
- impl Display for IntTy {
- fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
- match *self {
- IntTy::Isize => formatter.write_str("isize"),
- IntTy::I8 => formatter.write_str("i8"),
- IntTy::I16 => formatter.write_str("i16"),
- IntTy::I32 => formatter.write_str("i32"),
- IntTy::I64 => formatter.write_str("i64"),
- IntTy::Usize => formatter.write_str("usize"),
- IntTy::U8 => formatter.write_str("u8"),
- IntTy::U16 => formatter.write_str("u16"),
- IntTy::U32 => formatter.write_str("u32"),
- IntTy::U64 => formatter.write_str("u64"),
- IntTy::Unsuffixed => Ok(()),
- }
- }
- }
-
- impl Display for FloatTy {
- fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
- match *self {
- FloatTy::F32 => formatter.write_str("f32"),
- FloatTy::F64 => formatter.write_str("f64"),
- FloatTy::Unsuffixed => Ok(()),
- }
+ let kind = match self.value {
+ LitKind::Bool(true) => TokenKind::Word("true".into()),
+ LitKind::Bool(false) => TokenKind::Word("false".into()),
+ LitKind::Other(ref l) => TokenKind::Literal(l.clone()),
+ };
+ tokens.append(TokenTree {
+ span: self.span.0,
+ kind: kind,
+ });
}
}
}
diff --git a/src/mac.rs b/src/mac.rs
index dbed4eb..789bf82 100644
--- a/src/mac.rs
+++ b/src/mac.rs
@@ -1,5 +1,10 @@
+#[cfg(feature = "extra-traits")]
+use std::fmt;
+
use super::*;
+use proc_macro2::{TokenKind, Delimiter};
+
ast_struct! {
/// Represents a macro invocation. The Path indicates which macro
/// is being invoked, and the vector of token-trees contains the source
@@ -9,123 +14,141 @@
/// stored in the enclosing item. Oog.
pub struct Mac {
pub path: Path,
- pub tts: Vec<TokenTree>,
+ pub bang_token: tokens::Bang,
+ pub tokens: Vec<TokenTree>,
}
}
-ast_enum! {
- /// When the main rust parser encounters a syntax-extension invocation, it
- /// parses the arguments to the invocation as a token-tree. This is a very
- /// loose structure, such that all sorts of different AST-fragments can
- /// be passed to syntax extensions using a uniform type.
- ///
- /// If the syntax extension is an MBE macro, it will attempt to match its
- /// LHS token tree against the provided token tree, and if it finds a
- /// match, will transcribe the RHS token tree, splicing in any captured
- /// `macro_parser::matched_nonterminals` into the `SubstNt`s it finds.
- ///
- /// The RHS of an MBE macro is the only place `SubstNt`s are substituted.
- /// Nothing special happens to misnamed or misplaced `SubstNt`s.
- pub enum TokenTree {
- /// A single token
- Token(Token),
- /// A delimited sequence of token trees
- Delimited(Delimited),
+#[cfg_attr(feature = "clone-impls", derive(Clone))]
+pub struct TokenTree(pub proc_macro2::TokenTree);
+
+impl Mac {
+ pub fn is_braced(&self) -> bool {
+ match self.tokens.last() {
+ Some(t) => t.is_braced(),
+ None => false,
+ }
}
}
-ast_struct! {
- pub struct Delimited {
- /// The type of delimiter
- pub delim: DelimToken,
- /// The delimited sequence of token trees
- pub tts: Vec<TokenTree>,
+impl TokenTree {
+ pub fn is_braced(&self) -> bool {
+ match self.0.kind {
+ TokenKind::Sequence(Delimiter::Brace, _) => true,
+ _ => false,
+ }
}
}
-ast_enum! {
- pub enum Token {
- // Expression-operator symbols.
- Eq,
- Lt,
- Le,
- EqEq,
- Ne,
- Ge,
- Gt,
- AndAnd,
- OrOr,
- Not,
- Tilde,
- BinOp(BinOpToken),
- BinOpEq(BinOpToken),
+#[cfg(feature = "extra-traits")]
+impl PartialEq for TokenTree {
+ fn eq(&self, other: &TokenTree) -> bool {
+ use proc_macro2::OpKind;
- // Structural symbols
- At,
- Dot,
- DotDot,
- DotDotDot,
- Comma,
- Semi,
- Colon,
- ModSep,
- RArrow,
- LArrow,
- FatArrow,
- Pound,
- Dollar,
- Question,
+ match (&self.0.kind, &other.0.kind) {
+ (&TokenKind::Sequence(d1, ref s1), &TokenKind::Sequence(d2, ref s2)) => {
+ match (d1, d2) {
+ (Delimiter::Parenthesis, Delimiter::Parenthesis) |
+ (Delimiter::Brace, Delimiter::Brace) |
+ (Delimiter::Bracket, Delimiter::Bracket) => {}
+ (Delimiter::None, Delimiter::None) => {}
+ _ => return false,
+ }
- // Literals
- Literal(Lit),
+ let s1 = s1.clone().into_iter();
+ let mut s2 = s2.clone().into_iter();
- // Name components
- Ident(Ident),
- Underscore,
- Lifetime(Ident),
-
- DocComment(String),
+ for item1 in s1 {
+ let item2 = match s2.next() {
+ Some(item) => item,
+ None => return false,
+ };
+ if TokenTree(item1) != TokenTree(item2) {
+ return false
+ }
+ }
+ s2.next().is_none()
+ }
+ (&TokenKind::Op(o1, k1), &TokenKind::Op(o2, k2)) => {
+ o1 == o2 && match (k1, k2) {
+ (OpKind::Alone, OpKind::Alone) |
+ (OpKind::Joint, OpKind::Joint) => true,
+ _ => false,
+ }
+ }
+ (&TokenKind::Literal(ref l1), &TokenKind::Literal(ref l2)) => {
+ l1.to_string() == l2.to_string()
+ }
+ (&TokenKind::Word(ref s1), &TokenKind::Word(ref s2)) => {
+ s1.as_str() == s2.as_str()
+ }
+ _ => false,
+ }
}
}
-ast_enum! {
- #[cfg_attr(feature = "clone-impls", derive(Copy))]
- pub enum BinOpToken {
- Plus,
- Minus,
- Star,
- Slash,
- Percent,
- Caret,
- And,
- Or,
- Shl,
- Shr,
+#[cfg(feature = "extra-traits")]
+impl Eq for TokenTree {}
+
+#[cfg(feature = "extra-traits")]
+impl ::std::hash::Hash for TokenTree {
+ fn hash<H: ::std::hash::Hasher>(&self, h: &mut H) {
+ use proc_macro2::OpKind;
+
+ match self.0.kind {
+ TokenKind::Sequence(delim, ref stream) => {
+ 0u8.hash(h);
+ match delim {
+ Delimiter::Parenthesis => 0u8.hash(h),
+ Delimiter::Brace => 1u8.hash(h),
+ Delimiter::Bracket => 2u8.hash(h),
+ Delimiter::None => 3u8.hash(h),
+ }
+
+ for item in stream.clone().into_iter() {
+ TokenTree(item).hash(h);
+ }
+ 0xffu8.hash(h); // terminator w/ a variant we don't normally hash
+ }
+ TokenKind::Op(op, kind) => {
+ 1u8.hash(h);
+ op.hash(h);
+ match kind {
+ OpKind::Alone => 0u8.hash(h),
+ OpKind::Joint => 1u8.hash(h),
+ }
+ }
+ TokenKind::Literal(ref lit) => (2u8, lit.to_string()).hash(h),
+ TokenKind::Word(ref word) => (3u8, word.as_str()).hash(h),
+ }
}
}
-ast_enum! {
- /// A delimiter token
- #[cfg_attr(feature = "clone-impls", derive(Copy))]
- pub enum DelimToken {
- /// A round parenthesis: `(` or `)`
- Paren,
- /// A square bracket: `[` or `]`
- Bracket,
- /// A curly brace: `{` or `}`
- Brace,
+#[cfg(feature = "extra-traits")]
+impl fmt::Debug for TokenTree {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ self.0.to_string().fmt(f)
}
}
#[cfg(feature = "parsing")]
pub mod parsing {
use super::*;
- use Lifetime;
+ use {Lifetime};
use generics::parsing::lifetime;
use ident::parsing::word;
use lit::parsing::lit;
- use synom::space::{block_comment, whitespace};
+ use synom::IResult;
+ use synom::space::{block_comment, whitespace, skip_whitespace};
use ty::parsing::path;
+ use proc_macro2::{self, TokenStream, TokenKind, Delimiter, OpKind, Literal};
+
+ fn tt(kind: TokenKind) -> TokenTree {
+ TokenTree(proc_macro2::TokenTree {
+ kind: kind,
+ span: Default::default(),
+ })
+ }
named!(pub mac -> Mac, do_parse!(
what: path >>
@@ -133,146 +156,166 @@
body: delimited >>
(Mac {
path: what,
- tts: vec![TokenTree::Delimited(body)],
+ bang_token: tokens::Bang::default(),
+ tokens: vec![body],
})
));
named!(pub token_trees -> Vec<TokenTree>, many0!(token_tree));
- named!(pub delimited -> Delimited, alt!(
+ named!(pub token_stream -> TokenStream,
+ map!(token_trees, |t: Vec<TokenTree>| t.into_iter().map(|t| t.0).collect()));
+
+ named!(pub delimited -> TokenTree, alt!(
delimited!(
punct!("("),
- token_trees,
+ token_stream,
punct!(")")
- ) => { |tts| Delimited { delim: DelimToken::Paren, tts: tts } }
+ ) => { |ts| tt(TokenKind::Sequence(Delimiter::Parenthesis, ts)) }
|
delimited!(
punct!("["),
- token_trees,
+ token_stream,
punct!("]")
- ) => { |tts| Delimited { delim: DelimToken::Bracket, tts: tts } }
+ ) => { |ts| tt(TokenKind::Sequence(Delimiter::Bracket, ts)) }
|
delimited!(
punct!("{"),
- token_trees,
+ token_stream,
punct!("}")
- ) => { |tts| Delimited { delim: DelimToken::Brace, tts: tts } }
+ ) => { |ts| tt(TokenKind::Sequence(Delimiter::Brace, ts)) }
));
named!(pub token_tree -> TokenTree, alt!(
- map!(token, TokenTree::Token)
+ token
|
- map!(delimited, TokenTree::Delimited)
+ delimited
));
- named!(token -> Token, alt!(
- keyword!("_") => { |_| Token::Underscore }
+ macro_rules! punct1 {
+ ($i:expr, $punct:expr) => {
+ punct1($i, $punct)
+ }
+ }
+
+ fn punct1<'a>(input: &'a str, token: &'static str) -> IResult<&'a str, char> {
+ let input = skip_whitespace(input);
+ if input.starts_with(token) {
+ IResult::Done(&input[1..], token.chars().next().unwrap())
+ } else {
+ IResult::Error
+ }
+ }
+
+ named!(token -> TokenTree, alt!(
+ keyword!("_") => { |_| tt(TokenKind::Op('_', OpKind::Alone)) }
|
- punct!("&&") => { |_| Token::AndAnd } // must be before BinOp
+ punct1!("&&") => { |c| tt(TokenKind::Op(c, OpKind::Joint)) } // must be before BinOp
|
- punct!("||") => { |_| Token::OrOr } // must be before BinOp
+ punct1!("||") => { |c| tt(TokenKind::Op(c, OpKind::Joint)) } // must be before BinOp
|
- punct!("->") => { |_| Token::RArrow } // must be before BinOp
+ punct1!("->") => { |c| tt(TokenKind::Op(c, OpKind::Joint)) } // must be before BinOp
|
- punct!("<-") => { |_| Token::LArrow } // must be before Lt
+ punct1!("<-") => { |c| tt(TokenKind::Op(c, OpKind::Joint)) } // must be before Lt
|
- punct!("=>") => { |_| Token::FatArrow } // must be before Eq
+ punct1!("=>") => { |c| tt(TokenKind::Op(c, OpKind::Joint)) } // must be before Eq
|
- punct!("...") => { |_| Token::DotDotDot } // must be before DotDot
+ punct1!("...") => { |c| tt(TokenKind::Op(c, OpKind::Joint)) } // must be before DotDot
|
- punct!("..") => { |_| Token::DotDot } // must be before Dot
+ punct1!("..") => { |c| tt(TokenKind::Op(c, OpKind::Joint)) } // must be before Dot
|
- punct!(".") => { |_| Token::Dot }
+ punct1!(".") => { |c| tt(TokenKind::Op(c, OpKind::Alone)) }
|
- map!(doc_comment, Token::DocComment) // must be before bin_op
+ // must be before bin_op
+ map!(doc_comment, |s: String| tt(TokenKind::Literal(Literal::doccomment(&s))))
|
- map!(bin_op_eq, Token::BinOpEq) // must be before bin_op
+ bin_op_eq // must be before bin_op
|
- map!(bin_op, Token::BinOp)
+ bin_op
|
- map!(lit, Token::Literal)
+ map!(lit, |l: Lit| l.into_token_tree())
|
- map!(word, Token::Ident)
+ map!(word, |w: Ident| tt(TokenKind::Word(w.sym)))
|
- map!(lifetime, |lt: Lifetime| Token::Lifetime(lt.ident))
+ map!(lifetime, |lt: Lifetime| tt(TokenKind::Word(lt.ident.sym)))
|
- punct!("<=") => { |_| Token::Le }
+ punct1!("<=") => { |c| tt(TokenKind::Op(c, OpKind::Joint)) }
|
- punct!("==") => { |_| Token::EqEq }
+ punct1!("==") => { |c| tt(TokenKind::Op(c, OpKind::Joint)) }
|
- punct!("!=") => { |_| Token::Ne }
+ punct1!("!=") => { |c| tt(TokenKind::Op(c, OpKind::Joint)) }
|
- punct!(">=") => { |_| Token::Ge }
+ punct1!(">=") => { |c| tt(TokenKind::Op(c, OpKind::Joint)) }
|
- punct!("::") => { |_| Token::ModSep }
+ punct1!("::") => { |c| tt(TokenKind::Op(c, OpKind::Joint)) }
|
- punct!("=") => { |_| Token::Eq }
+ punct1!("=") => { |c| tt(TokenKind::Op(c, OpKind::Alone)) }
|
- punct!("<") => { |_| Token::Lt }
+ punct1!("<") => { |c| tt(TokenKind::Op(c, OpKind::Alone)) }
|
- punct!(">") => { |_| Token::Gt }
+ punct1!(">") => { |c| tt(TokenKind::Op(c, OpKind::Alone)) }
|
- punct!("!") => { |_| Token::Not }
+ punct1!("!") => { |c| tt(TokenKind::Op(c, OpKind::Alone)) }
|
- punct!("~") => { |_| Token::Tilde }
+ punct1!("~") => { |c| tt(TokenKind::Op(c, OpKind::Alone)) }
|
- punct!("@") => { |_| Token::At }
+ punct1!("@") => { |c| tt(TokenKind::Op(c, OpKind::Alone)) }
|
- punct!(",") => { |_| Token::Comma }
+ punct1!(",") => { |c| tt(TokenKind::Op(c, OpKind::Alone)) }
|
- punct!(";") => { |_| Token::Semi }
+ punct1!(";") => { |c| tt(TokenKind::Op(c, OpKind::Alone)) }
|
- punct!(":") => { |_| Token::Colon }
+ punct1!(":") => { |c| tt(TokenKind::Op(c, OpKind::Alone)) }
|
- punct!("#") => { |_| Token::Pound }
+ punct1!("#") => { |c| tt(TokenKind::Op(c, OpKind::Alone)) }
|
- punct!("$") => { |_| Token::Dollar }
+ punct1!("$") => { |c| tt(TokenKind::Op(c, OpKind::Alone)) }
|
- punct!("?") => { |_| Token::Question }
+ punct1!("?") => { |c| tt(TokenKind::Op(c, OpKind::Alone)) }
));
- named!(bin_op -> BinOpToken, alt!(
- punct!("+") => { |_| BinOpToken::Plus }
+ named!(bin_op -> TokenTree, alt!(
+ punct1!("+") => { |c| tt(TokenKind::Op(c, OpKind::Alone)) }
|
- punct!("-") => { |_| BinOpToken::Minus }
+ punct1!("-") => { |c| tt(TokenKind::Op(c, OpKind::Alone)) }
|
- punct!("*") => { |_| BinOpToken::Star }
+ punct1!("*") => { |c| tt(TokenKind::Op(c, OpKind::Alone)) }
|
- punct!("/") => { |_| BinOpToken::Slash }
+ punct1!("/") => { |c| tt(TokenKind::Op(c, OpKind::Alone)) }
|
- punct!("%") => { |_| BinOpToken::Percent }
+ punct1!("%") => { |c| tt(TokenKind::Op(c, OpKind::Alone)) }
|
- punct!("^") => { |_| BinOpToken::Caret }
+ punct1!("^") => { |c| tt(TokenKind::Op(c, OpKind::Alone)) }
|
- punct!("&") => { |_| BinOpToken::And }
+ punct1!("&") => { |c| tt(TokenKind::Op(c, OpKind::Alone)) }
|
- punct!("|") => { |_| BinOpToken::Or }
+ punct1!("|") => { |c| tt(TokenKind::Op(c, OpKind::Alone)) }
|
- punct!("<<") => { |_| BinOpToken::Shl }
+ punct1!("<<") => { |c| tt(TokenKind::Op(c, OpKind::Joint)) }
|
- punct!(">>") => { |_| BinOpToken::Shr }
+ punct1!(">>") => { |c| tt(TokenKind::Op(c, OpKind::Joint)) }
));
- named!(bin_op_eq -> BinOpToken, alt!(
- punct!("+=") => { |_| BinOpToken::Plus }
+ named!(bin_op_eq -> TokenTree, alt!(
+ punct1!("+=") => { |c| tt(TokenKind::Op(c, OpKind::Joint)) }
|
- punct!("-=") => { |_| BinOpToken::Minus }
+ punct1!("-=") => { |c| tt(TokenKind::Op(c, OpKind::Joint)) }
|
- punct!("*=") => { |_| BinOpToken::Star }
+ punct1!("*=") => { |c| tt(TokenKind::Op(c, OpKind::Joint)) }
|
- punct!("/=") => { |_| BinOpToken::Slash }
+ punct1!("/=") => { |c| tt(TokenKind::Op(c, OpKind::Joint)) }
|
- punct!("%=") => { |_| BinOpToken::Percent }
+ punct1!("%=") => { |c| tt(TokenKind::Op(c, OpKind::Joint)) }
|
- punct!("^=") => { |_| BinOpToken::Caret }
+ punct1!("^=") => { |c| tt(TokenKind::Op(c, OpKind::Joint)) }
|
- punct!("&=") => { |_| BinOpToken::And }
+ punct1!("&=") => { |c| tt(TokenKind::Op(c, OpKind::Joint)) }
|
- punct!("|=") => { |_| BinOpToken::Or }
+ punct1!("|=") => { |c| tt(TokenKind::Op(c, OpKind::Joint)) }
|
- punct!("<<=") => { |_| BinOpToken::Shl }
+ punct1!("<<=") => { |c| tt(TokenKind::Op(c, OpKind::Joint)) }
|
- punct!(">>=") => { |_| BinOpToken::Shr }
+ punct1!(">>=") => { |c| tt(TokenKind::Op(c, OpKind::Joint)) }
));
named!(doc_comment -> String, alt!(
@@ -313,126 +356,14 @@
impl ToTokens for Mac {
fn to_tokens(&self, tokens: &mut Tokens) {
self.path.to_tokens(tokens);
- tokens.append("!");
- for tt in &self.tts {
- tt.to_tokens(tokens);
- }
+ self.bang_token.to_tokens(tokens);
+ tokens.append_all(&self.tokens);
}
}
impl ToTokens for TokenTree {
fn to_tokens(&self, tokens: &mut Tokens) {
- match *self {
- TokenTree::Token(ref token) => token.to_tokens(tokens),
- TokenTree::Delimited(ref delimited) => delimited.to_tokens(tokens),
- }
- }
- }
-
- impl DelimToken {
- fn open(&self) -> &'static str {
- match *self {
- DelimToken::Paren => "(",
- DelimToken::Bracket => "[",
- DelimToken::Brace => "{",
- }
- }
-
- fn close(&self) -> &'static str {
- match *self {
- DelimToken::Paren => ")",
- DelimToken::Bracket => "]",
- DelimToken::Brace => "}",
- }
- }
- }
-
- impl ToTokens for Delimited {
- fn to_tokens(&self, tokens: &mut Tokens) {
- tokens.append(self.delim.open());
- for tt in &self.tts {
- tt.to_tokens(tokens);
- }
- tokens.append(self.delim.close());
- }
- }
-
- impl ToTokens for Token {
- fn to_tokens(&self, tokens: &mut Tokens) {
- match *self {
- Token::Eq => tokens.append("="),
- Token::Lt => tokens.append("<"),
- Token::Le => tokens.append("<="),
- Token::EqEq => tokens.append("=="),
- Token::Ne => tokens.append("!="),
- Token::Ge => tokens.append(">="),
- Token::Gt => tokens.append(">"),
- Token::AndAnd => tokens.append("&&"),
- Token::OrOr => tokens.append("||"),
- Token::Not => tokens.append("!"),
- Token::Tilde => tokens.append("~"),
- Token::BinOp(ref binop) => tokens.append(binop.op()),
- Token::BinOpEq(ref binop) => tokens.append(binop.assign_op()),
- Token::At => tokens.append("@"),
- Token::Dot => tokens.append("."),
- Token::DotDot => tokens.append(".."),
- Token::DotDotDot => tokens.append("..."),
- Token::Comma => tokens.append(","),
- Token::Semi => tokens.append(";"),
- Token::Colon => tokens.append(":"),
- Token::ModSep => tokens.append("::"),
- Token::RArrow => tokens.append("->"),
- Token::LArrow => tokens.append("<-"),
- Token::FatArrow => tokens.append("=>"),
- Token::Pound => tokens.append("#"),
- Token::Dollar => tokens.append("$"),
- Token::Question => tokens.append("?"),
- Token::Literal(ref lit) => lit.to_tokens(tokens),
- Token::Ident(ref ident) |
- Token::Lifetime(ref ident) => ident.to_tokens(tokens),
- Token::Underscore => tokens.append("_"),
- Token::DocComment(ref com) => {
- tokens.append(&format!("{}\n", com));
- }
- }
- }
- }
-
- impl BinOpToken {
- fn op(&self) -> &'static str {
- match *self {
- BinOpToken::Plus => "+",
- BinOpToken::Minus => "-",
- BinOpToken::Star => "*",
- BinOpToken::Slash => "/",
- BinOpToken::Percent => "%",
- BinOpToken::Caret => "^",
- BinOpToken::And => "&",
- BinOpToken::Or => "|",
- BinOpToken::Shl => "<<",
- BinOpToken::Shr => ">>",
- }
- }
-
- fn assign_op(&self) -> &'static str {
- match *self {
- BinOpToken::Plus => "+=",
- BinOpToken::Minus => "-=",
- BinOpToken::Star => "*=",
- BinOpToken::Slash => "/=",
- BinOpToken::Percent => "%=",
- BinOpToken::Caret => "^=",
- BinOpToken::And => "&=",
- BinOpToken::Or => "|=",
- BinOpToken::Shl => "<<=",
- BinOpToken::Shr => ">>=",
- }
- }
- }
-
- impl ToTokens for BinOpToken {
- fn to_tokens(&self, tokens: &mut Tokens) {
- tokens.append(self.op());
+ self.0.to_tokens(tokens);
}
}
}
diff --git a/src/op.rs b/src/op.rs
index 6393e00..636b974 100644
--- a/src/op.rs
+++ b/src/op.rs
@@ -1,42 +1,64 @@
+use tokens;
+
ast_enum! {
#[cfg_attr(feature = "clone-impls", derive(Copy))]
pub enum BinOp {
/// The `+` operator (addition)
- Add,
+ Add(tokens::Add),
/// The `-` operator (subtraction)
- Sub,
+ Sub(tokens::Sub),
/// The `*` operator (multiplication)
- Mul,
+ Mul(tokens::Star),
/// The `/` operator (division)
- Div,
+ Div(tokens::Div),
/// The `%` operator (modulus)
- Rem,
+ Rem(tokens::Rem),
/// The `&&` operator (logical and)
- And,
+ And(tokens::AndAnd),
/// The `||` operator (logical or)
- Or,
+ Or(tokens::OrOr),
/// The `^` operator (bitwise xor)
- BitXor,
+ BitXor(tokens::Caret),
/// The `&` operator (bitwise and)
- BitAnd,
+ BitAnd(tokens::And),
/// The `|` operator (bitwise or)
- BitOr,
+ BitOr(tokens::Or),
/// The `<<` operator (shift left)
- Shl,
+ Shl(tokens::Shl),
/// The `>>` operator (shift right)
- Shr,
+ Shr(tokens::Shr),
/// The `==` operator (equality)
- Eq,
+ Eq(tokens::EqEq),
/// The `<` operator (less than)
- Lt,
+ Lt(tokens::Lt),
/// The `<=` operator (less than or equal to)
- Le,
+ Le(tokens::Le),
/// The `!=` operator (not equal to)
- Ne,
+ Ne(tokens::Ne),
/// The `>=` operator (greater than or equal to)
- Ge,
+ Ge(tokens::Ge),
/// The `>` operator (greater than)
- Gt,
+ Gt(tokens::Gt),
+ /// The `+=` operator
+ AddEq(tokens::AddEq),
+ /// The `-=` operator
+ SubEq(tokens::SubEq),
+ /// The `*=` operator
+ MulEq(tokens::MulEq),
+ /// The `/=` operator
+ DivEq(tokens::DivEq),
+ /// The `%=` operator
+ RemEq(tokens::RemEq),
+ /// The `^=` operator
+ BitXorEq(tokens::CaretEq),
+ /// The `&=` operator
+ BitAndEq(tokens::AndEq),
+ /// The `|=` operator
+ BitOrEq(tokens::OrEq),
+ /// The `<<=` operator
+ ShlEq(tokens::ShlEq),
+ /// The `>>=` operator
+ ShrEq(tokens::ShrEq),
}
}
@@ -44,11 +66,11 @@
#[cfg_attr(feature = "clone-impls", derive(Copy))]
pub enum UnOp {
/// The `*` operator for dereferencing
- Deref,
+ Deref(tokens::Star),
/// The `!` operator for logical inversion
- Not,
+ Not(tokens::Bang),
/// The `-` operator for negation
- Neg,
+ Neg(tokens::Sub),
}
}
@@ -57,72 +79,72 @@
use super::*;
named!(pub binop -> BinOp, alt!(
- punct!("&&") => { |_| BinOp::And }
+ punct!("&&") => { |_| BinOp::And(tokens::AndAnd::default()) }
|
- punct!("||") => { |_| BinOp::Or }
+ punct!("||") => { |_| BinOp::Or(tokens::OrOr::default()) }
|
- punct!("<<") => { |_| BinOp::Shl }
+ punct!("<<") => { |_| BinOp::Shl(tokens::Shl::default()) }
|
- punct!(">>") => { |_| BinOp::Shr }
+ punct!(">>") => { |_| BinOp::Shr(tokens::Shr::default()) }
|
- punct!("==") => { |_| BinOp::Eq }
+ punct!("==") => { |_| BinOp::Eq(tokens::EqEq::default()) }
|
- punct!("<=") => { |_| BinOp::Le }
+ punct!("<=") => { |_| BinOp::Le(tokens::Le::default()) }
|
- punct!("!=") => { |_| BinOp::Ne }
+ punct!("!=") => { |_| BinOp::Ne(tokens::Ne::default()) }
|
- punct!(">=") => { |_| BinOp::Ge }
+ punct!(">=") => { |_| BinOp::Ge(tokens::Ge::default()) }
|
- punct!("+") => { |_| BinOp::Add }
+ punct!("+") => { |_| BinOp::Add(tokens::Add::default()) }
|
- punct!("-") => { |_| BinOp::Sub }
+ punct!("-") => { |_| BinOp::Sub(tokens::Sub::default()) }
|
- punct!("*") => { |_| BinOp::Mul }
+ punct!("*") => { |_| BinOp::Mul(tokens::Star::default()) }
|
- punct!("/") => { |_| BinOp::Div }
+ punct!("/") => { |_| BinOp::Div(tokens::Div::default()) }
|
- punct!("%") => { |_| BinOp::Rem }
+ punct!("%") => { |_| BinOp::Rem(tokens::Rem::default()) }
|
- punct!("^") => { |_| BinOp::BitXor }
+ punct!("^") => { |_| BinOp::BitXor(tokens::Caret::default()) }
|
- punct!("&") => { |_| BinOp::BitAnd }
+ punct!("&") => { |_| BinOp::BitAnd(tokens::And::default()) }
|
- punct!("|") => { |_| BinOp::BitOr }
+ punct!("|") => { |_| BinOp::BitOr(tokens::Or::default()) }
|
- punct!("<") => { |_| BinOp::Lt }
+ punct!("<") => { |_| BinOp::Lt(tokens::Lt::default()) }
|
- punct!(">") => { |_| BinOp::Gt }
+ punct!(">") => { |_| BinOp::Gt(tokens::Gt::default()) }
));
#[cfg(feature = "full")]
named!(pub assign_op -> BinOp, alt!(
- punct!("+=") => { |_| BinOp::Add }
+ punct!("+=") => { |_| BinOp::AddEq(tokens::AddEq::default()) }
|
- punct!("-=") => { |_| BinOp::Sub }
+ punct!("-=") => { |_| BinOp::SubEq(tokens::SubEq::default()) }
|
- punct!("*=") => { |_| BinOp::Mul }
+ punct!("*=") => { |_| BinOp::MulEq(tokens::MulEq::default()) }
|
- punct!("/=") => { |_| BinOp::Div }
+ punct!("/=") => { |_| BinOp::DivEq(tokens::DivEq::default()) }
|
- punct!("%=") => { |_| BinOp::Rem }
+ punct!("%=") => { |_| BinOp::RemEq(tokens::RemEq::default()) }
|
- punct!("^=") => { |_| BinOp::BitXor }
+ punct!("^=") => { |_| BinOp::BitXorEq(tokens::CaretEq::default()) }
|
- punct!("&=") => { |_| BinOp::BitAnd }
+ punct!("&=") => { |_| BinOp::BitAndEq(tokens::AndEq::default()) }
|
- punct!("|=") => { |_| BinOp::BitOr }
+ punct!("|=") => { |_| BinOp::BitOrEq(tokens::OrEq::default()) }
|
- punct!("<<=") => { |_| BinOp::Shl }
+ punct!("<<=") => { |_| BinOp::ShlEq(tokens::ShlEq::default()) }
|
- punct!(">>=") => { |_| BinOp::Shr }
+ punct!(">>=") => { |_| BinOp::ShrEq(tokens::ShrEq::default()) }
));
named!(pub unop -> UnOp, alt!(
- punct!("*") => { |_| UnOp::Deref }
+ punct!("*") => { |_| UnOp::Deref(tokens::Star::default()) }
|
- punct!("!") => { |_| UnOp::Not }
+ punct!("!") => { |_| UnOp::Not(tokens::Bang::default()) }
|
- punct!("-") => { |_| UnOp::Neg }
+ punct!("-") => { |_| UnOp::Neg(tokens::Sub::default()) }
));
}
@@ -131,66 +153,48 @@
use super::*;
use quote::{Tokens, ToTokens};
- impl BinOp {
- pub fn op(&self) -> &'static str {
- match *self {
- BinOp::Add => "+",
- BinOp::Sub => "-",
- BinOp::Mul => "*",
- BinOp::Div => "/",
- BinOp::Rem => "%",
- BinOp::And => "&&",
- BinOp::Or => "||",
- BinOp::BitXor => "^",
- BinOp::BitAnd => "&",
- BinOp::BitOr => "|",
- BinOp::Shl => "<<",
- BinOp::Shr => ">>",
- BinOp::Eq => "==",
- BinOp::Lt => "<",
- BinOp::Le => "<=",
- BinOp::Ne => "!=",
- BinOp::Ge => ">=",
- BinOp::Gt => ">",
- }
- }
-
- pub fn assign_op(&self) -> Option<&'static str> {
- match *self {
- BinOp::Add => Some("+="),
- BinOp::Sub => Some("-="),
- BinOp::Mul => Some("*="),
- BinOp::Div => Some("/="),
- BinOp::Rem => Some("%="),
- BinOp::BitXor => Some("^="),
- BinOp::BitAnd => Some("&="),
- BinOp::BitOr => Some("|="),
- BinOp::Shl => Some("<<="),
- BinOp::Shr => Some(">>="),
- _ => None,
- }
- }
- }
-
impl ToTokens for BinOp {
fn to_tokens(&self, tokens: &mut Tokens) {
- tokens.append(self.op());
- }
- }
-
- impl UnOp {
- pub fn op(&self) -> &'static str {
match *self {
- UnOp::Deref => "*",
- UnOp::Not => "!",
- UnOp::Neg => "-",
+ BinOp::Add(ref t) => t.to_tokens(tokens),
+ BinOp::Sub(ref t) => t.to_tokens(tokens),
+ BinOp::Mul(ref t) => t.to_tokens(tokens),
+ BinOp::Div(ref t) => t.to_tokens(tokens),
+ BinOp::Rem(ref t) => t.to_tokens(tokens),
+ BinOp::And(ref t) => t.to_tokens(tokens),
+ BinOp::Or(ref t) => t.to_tokens(tokens),
+ BinOp::BitXor(ref t) => t.to_tokens(tokens),
+ BinOp::BitAnd(ref t) => t.to_tokens(tokens),
+ BinOp::BitOr(ref t) => t.to_tokens(tokens),
+ BinOp::Shl(ref t) => t.to_tokens(tokens),
+ BinOp::Shr(ref t) => t.to_tokens(tokens),
+ BinOp::Eq(ref t) => t.to_tokens(tokens),
+ BinOp::Lt(ref t) => t.to_tokens(tokens),
+ BinOp::Le(ref t) => t.to_tokens(tokens),
+ BinOp::Ne(ref t) => t.to_tokens(tokens),
+ BinOp::Ge(ref t) => t.to_tokens(tokens),
+ BinOp::Gt(ref t) => t.to_tokens(tokens),
+ BinOp::AddEq(ref t) => t.to_tokens(tokens),
+ BinOp::SubEq(ref t) => t.to_tokens(tokens),
+ BinOp::MulEq(ref t) => t.to_tokens(tokens),
+ BinOp::DivEq(ref t) => t.to_tokens(tokens),
+ BinOp::RemEq(ref t) => t.to_tokens(tokens),
+ BinOp::BitXorEq(ref t) => t.to_tokens(tokens),
+ BinOp::BitAndEq(ref t) => t.to_tokens(tokens),
+ BinOp::BitOrEq(ref t) => t.to_tokens(tokens),
+ BinOp::ShlEq(ref t) => t.to_tokens(tokens),
+ BinOp::ShrEq(ref t) => t.to_tokens(tokens),
}
}
}
impl ToTokens for UnOp {
fn to_tokens(&self, tokens: &mut Tokens) {
- tokens.append(self.op());
+ match *self {
+ UnOp::Deref(ref t) => t.to_tokens(tokens),
+ UnOp::Not(ref t) => t.to_tokens(tokens),
+ UnOp::Neg(ref t) => t.to_tokens(tokens),
+ }
}
}
}
diff --git a/src/span.rs b/src/span.rs
new file mode 100644
index 0000000..a652c41
--- /dev/null
+++ b/src/span.rs
@@ -0,0 +1,27 @@
+use std::hash::{Hash, Hasher};
+use std::fmt;
+
+use proc_macro2;
+
+#[derive(Clone, Copy, Default)]
+pub struct Span(pub proc_macro2::Span);
+
+impl PartialEq for Span {
+ fn eq(&self, _other: &Span) -> bool {
+ true
+ }
+}
+
+impl Eq for Span {}
+
+impl Hash for Span {
+ fn hash<H: Hasher>(&self, _hasher: &mut H) {
+ }
+}
+
+impl fmt::Debug for Span {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_struct("Span")
+ .finish()
+ }
+}
diff --git a/src/tokens.rs b/src/tokens.rs
new file mode 100644
index 0000000..744cb97
--- /dev/null
+++ b/src/tokens.rs
@@ -0,0 +1,205 @@
+use Span;
+
+macro_rules! tokens {
+ (
+ ops: {
+ $(($($op:tt)*),)*
+ }
+ delim: {
+ $(($($delim:tt)*),)*
+ }
+ syms: {
+ $(($($sym:tt)*),)*
+ }
+ ) => (
+ $(op! { $($op)* })*
+ $(delim! { $($delim)* })*
+ $(sym! { $($sym)* })*
+ )
+}
+
+macro_rules! op {
+ (pub struct $name:ident($($contents:tt)*) => $s:expr) => {
+ ast_struct! {
+ #[cfg_attr(feature = "clone-impls", derive(Copy))]
+ #[derive(Default)]
+ pub struct $name(pub $($contents)*);
+ }
+
+ #[cfg(feature = "printing")]
+ impl ::quote::ToTokens for $name {
+ fn to_tokens(&self, tokens: &mut ::quote::Tokens) {
+ printing::op($s, &self.0, tokens);
+ }
+ }
+ }
+}
+
+macro_rules! sym {
+ (pub struct $name:ident => $s:expr) => {
+ ast_struct! {
+ #[cfg_attr(feature = "clone-impls", derive(Copy))]
+ #[derive(Default)]
+ pub struct $name(pub Span);
+ }
+
+ #[cfg(feature = "printing")]
+ impl ::quote::ToTokens for $name {
+ fn to_tokens(&self, tokens: &mut ::quote::Tokens) {
+ printing::sym($s, &self.0, tokens);
+ }
+ }
+ }
+}
+
+macro_rules! delim {
+ (pub struct $name:ident => $s:expr) => {
+ ast_struct! {
+ #[cfg_attr(feature = "clone-impls", derive(Copy))]
+ #[derive(Default)]
+ pub struct $name(pub Span);
+ }
+
+ #[cfg(feature = "printing")]
+ impl $name {
+ pub fn surround<F>(&self,
+ tokens: &mut ::quote::Tokens,
+ f: F)
+ where F: FnOnce(&mut ::quote::Tokens)
+ {
+ printing::delim($s, &self.0, tokens, f);
+ }
+ }
+ }
+}
+
+tokens! {
+ ops: {
+ (pub struct Add([Span; 1]) => "+"),
+ (pub struct AddEq([Span; 2]) => "+="),
+ (pub struct And([Span; 1]) => "&"),
+ (pub struct AndAnd([Span; 2]) => "&&"),
+ (pub struct AndEq([Span; 2]) => "&="),
+ (pub struct At([Span; 1]) => "@"),
+ (pub struct Bang([Span; 1]) => "!"),
+ (pub struct Caret([Span; 1]) => "^"),
+ (pub struct CaretEq([Span; 2]) => "^="),
+ (pub struct Colon([Span; 1]) => ":"),
+ (pub struct Colon2([Span; 2]) => "::"),
+ (pub struct Comma([Span; 1]) => ","),
+ (pub struct Div([Span; 1]) => "/"),
+ (pub struct DivEq([Span; 2]) => "/="),
+ (pub struct Dot([Span; 1]) => "."),
+ (pub struct Dot2([Span; 2]) => ".."),
+ (pub struct Dot3([Span; 3]) => "..."),
+ (pub struct Eq([Span; 1]) => "="),
+ (pub struct EqEq([Span; 2]) => "=="),
+ (pub struct Ge([Span; 2]) => ">="),
+ (pub struct Gt([Span; 1]) => ">"),
+ (pub struct Le([Span; 2]) => "<="),
+ (pub struct Lt([Span; 1]) => "<"),
+ (pub struct MulEq([Span; 2]) => "*="),
+ (pub struct Ne([Span; 2]) => "!="),
+ (pub struct Or([Span; 1]) => "|"),
+ (pub struct OrEq([Span; 2]) => "|="),
+ (pub struct OrOr([Span; 2]) => "||"),
+ (pub struct Pound([Span; 1]) => "#"),
+ (pub struct Question([Span; 1]) => "?"),
+ (pub struct RArrow([Span; 2]) => "->"),
+ (pub struct Rem([Span; 1]) => "%"),
+ (pub struct RemEq([Span; 2]) => "%="),
+ (pub struct Rocket([Span; 2]) => "=>"),
+ (pub struct Semi([Span; 1]) => ";"),
+ (pub struct Shl([Span; 2]) => "<<"),
+ (pub struct ShlEq([Span; 3]) => "<<="),
+ (pub struct Shr([Span; 2]) => ">>"),
+ (pub struct ShrEq([Span; 3]) => ">>="),
+ (pub struct Star([Span; 1]) => "*"),
+ (pub struct Sub([Span; 1]) => "-"),
+ (pub struct SubEq([Span; 2]) => "-="),
+ (pub struct Underscore([Span; 1]) => "_"),
+ }
+ delim: {
+ (pub struct Brace => "{"),
+ (pub struct Bracket => "["),
+ (pub struct Paren => "("),
+ }
+ syms: {
+ (pub struct As => "as"),
+ (pub struct Box => "box"),
+ (pub struct Break => "break"),
+ (pub struct Catch => "catch"),
+ (pub struct Const => "const"),
+ (pub struct Continue => "continue"),
+ (pub struct Crate => "crate"),
+ (pub struct Default => "default"),
+ (pub struct Do => "do"),
+ (pub struct Else => "else"),
+ (pub struct Enum => "enum"),
+ (pub struct Extern => "extern"),
+ (pub struct Fn => "fn"),
+ (pub struct For => "for"),
+ (pub struct If => "if"),
+ (pub struct Impl => "impl"),
+ (pub struct In => "in"),
+ (pub struct Let => "let"),
+ (pub struct Loop => "loop"),
+ (pub struct Match => "match"),
+ (pub struct Mod => "mod"),
+ (pub struct Move => "move"),
+ (pub struct Mut => "mut"),
+ (pub struct Pub => "pub"),
+ (pub struct Ref => "ref"),
+ (pub struct Return => "return"),
+ (pub struct Self_ => "self"),
+ (pub struct Static => "static"),
+ (pub struct Struct => "struct"),
+ (pub struct Trait => "trait"),
+ (pub struct Type => "type"),
+ (pub struct Union => "union"),
+ (pub struct Unsafe => "unsafe"),
+ (pub struct Use => "use"),
+ (pub struct Where => "where"),
+ (pub struct While => "while"),
+ }
+}
+
+#[cfg(feature = "printing")]
+mod printing {
+ use Span;
+ use proc_macro2::{TokenTree, TokenKind, OpKind};
+ use quote::Tokens;
+
+ pub fn op(s: &str, spans: &[Span], tokens: &mut Tokens) {
+ assert_eq!(s.len(), spans.len());
+
+ let mut chars = s.chars();
+ let mut spans = spans.iter();
+ let ch = chars.next_back().unwrap();
+ let span = spans.next_back().unwrap();
+ for (ch, span) in chars.zip(spans) {
+ tokens.append(TokenTree {
+ span: span.0,
+ kind: TokenKind::Op(ch, OpKind::Joint),
+ });
+ }
+
+ tokens.append(TokenTree {
+ span: span.0,
+ kind: TokenKind::Op(ch, OpKind::Alone),
+ });
+ }
+
+ pub fn sym(s: &str, span: &Span, tokens: &mut Tokens) {
+ tokens.append(TokenTree {
+ span: span.0,
+ kind: TokenKind::Word(s.into()),
+ });
+ }
+
+ pub fn delim<F>(s: &str, span: &Span, tokens: &mut Tokens, f: F)
+ where F: FnOnce(&mut Tokens)
+ {
+ tokens.append_delimited(s, span.0, f)
+ }
+}
diff --git a/src/ty.rs b/src/ty.rs
index 7345da7..45fb637 100644
--- a/src/ty.rs
+++ b/src/ty.rs
@@ -1,3 +1,4 @@
+use delimited::Delimited;
use super::*;
ast_enum_of_structs! {
@@ -6,18 +7,24 @@
/// A variable-length array (`[T]`)
pub Slice(TySlice {
pub ty: Box<Ty>,
+ pub bracket_token: tokens::Bracket,
}),
/// A fixed length array (`[T; n]`)
pub Array(TyArray {
+ pub bracket_token: tokens::Bracket,
pub ty: Box<Ty>,
+ pub semi_token: tokens::Semi,
pub amt: ConstExpr,
}),
/// A raw pointer (`*const T` or `*mut T`)
pub Ptr(TyPtr {
+ pub star_token: tokens::Star,
+ pub const_token: Option<tokens::Const>,
pub ty: Box<MutTy>,
}),
/// A reference (`&'a T` or `&'a mut T`)
pub Rptr(TyRptr {
+ pub and_token: tokens::And,
pub lifetime: Option<Lifetime>,
pub ty: Box<MutTy>,
}),
@@ -26,10 +33,14 @@
pub ty: Box<BareFnTy>,
}),
/// The never type (`!`)
- pub Never(TyNever {}),
+ pub Never(TyNever {
+ pub bang_token: tokens::Bang,
+ }),
/// A tuple (`(A, B, C, D, ...)`)
pub Tup(TyTup {
- pub tys: Vec<Ty>,
+ pub paren_token: tokens::Paren,
+ pub tys: Delimited<Ty, tokens::Comma>,
+ pub lone_comma: Option<tokens::Comma>,
}),
/// A path (`module::module::...::Type`), optionally
/// "qualified", e.g. `<Vec<T> as SomeTrait>::SomeType`.
@@ -42,20 +53,24 @@
/// A trait object type `Bound1 + Bound2 + Bound3`
/// where `Bound` is a trait or a lifetime.
pub TraitObject(TyTraitObject {
- pub bounds: Vec<TyParamBound>,
+ pub bounds: Delimited<TyParamBound, tokens::Add>,
}),
/// An `impl Bound1 + Bound2 + Bound3` type
/// where `Bound` is a trait or a lifetime.
pub ImplTrait(TyImplTrait {
- pub bounds: Vec<TyParamBound>,
+ pub impl_token: tokens::Impl,
+ pub bounds: Delimited<TyParamBound, tokens::Add>,
}),
/// No-op; kept solely so that we can pretty-print faithfully
pub Paren(TyParen {
+ pub paren_token: tokens::Paren,
pub ty: Box<Ty>,
}),
/// TyKind::Infer means the type should be inferred instead of it having been
/// specified. This can appear anywhere in a type.
- pub Infer(TyInfer {}),
+ pub Infer(TyInfer {
+ pub underscore_token: tokens::Underscore
+ }),
/// A macro in the type position.
pub Mac(Mac),
}
@@ -71,7 +86,7 @@
ast_enum! {
#[cfg_attr(feature = "clone-impls", derive(Copy))]
pub enum Mutability {
- Mutable,
+ Mutable(tokens::Mut),
Immutable,
}
}
@@ -87,18 +102,25 @@
/// A `::foo` path, is relative to the crate root rather than current
/// module (like paths in an import).
pub global: bool,
+ pub leading_colon: Option<tokens::Colon2>,
/// The segments in the path: the things separated by `::`.
- pub segments: Vec<PathSegment>,
+ pub segments: Delimited<PathSegment, tokens::Colon2>,
}
}
+#[cfg(feature = "printing")]
+ast_struct! {
+ pub struct PathTokens<'a>(pub &'a Option<QSelf>, pub &'a Path);
+}
+
impl<T> From<T> for Path
where T: Into<PathSegment>
{
fn from(segment: T) -> Self {
Path {
global: false,
- segments: vec![segment.into()],
+ leading_colon: None,
+ segments: vec![(segment.into(), None)].into(),
}
}
}
@@ -162,14 +184,17 @@
/// A path like `Foo<'a, T>`
#[derive(Default)]
pub struct AngleBracketedParameterData {
+ pub lt_token: Option<tokens::Lt>,
+ pub gt_token: Option<tokens::Gt>,
+
/// The lifetime parameters for this path segment.
- pub lifetimes: Vec<Lifetime>,
+ pub lifetimes: Delimited<Lifetime, tokens::Comma>,
/// The type parameters for this path segment, if present.
- pub types: Vec<Ty>,
+ pub types: Delimited<Ty, tokens::Comma>,
/// Bindings (equality constraints) on associated types, if present.
///
/// E.g., `Foo<A=Bar>`.
- pub bindings: Vec<TypeBinding>,
+ pub bindings: Delimited<TypeBinding, tokens::Comma>,
}
}
@@ -177,6 +202,7 @@
/// Bind a type to an associated type: `A=Foo`.
pub struct TypeBinding {
pub ident: Ident,
+ pub eq_token: tokens::Eq,
pub ty: Ty,
}
}
@@ -185,17 +211,18 @@
ast_struct! {
/// A path like `Foo(A,B) -> C`
pub struct ParenthesizedParameterData {
+ pub paren_token: tokens::Paren,
/// `(A, B)`
- pub inputs: Vec<Ty>,
+ pub inputs: Delimited<Ty, tokens::Comma>,
/// `C`
- pub output: Option<Ty>,
+ pub output: FunctionRetTy,
}
}
ast_struct! {
pub struct PolyTraitRef {
- /// The `'a` in `<'a> Foo<&'a T>`
- pub bound_lifetimes: Vec<LifetimeDef>,
+ /// The `for<'a>` in `for<'a> Foo<&'a T>`
+ pub bound_lifetimes: Option<BoundLifetimes>,
/// The `Foo<&'a T>` in `<'a> Foo<&'a T>`
pub trait_ref: Path,
}
@@ -217,6 +244,9 @@
/// ty position = 0
/// ```
pub struct QSelf {
+ pub lt_token: tokens::Lt,
+ pub gt_token: tokens::Gt,
+ pub as_token: Option<tokens::As>,
pub ty: Box<Ty>,
pub position: usize,
}
@@ -224,27 +254,36 @@
ast_struct! {
pub struct BareFnTy {
+ pub lifetimes: Option<BoundLifetimes>,
pub unsafety: Unsafety,
pub abi: Option<Abi>,
- pub lifetimes: Vec<LifetimeDef>,
- pub inputs: Vec<BareFnArg>,
+ pub fn_token: tokens::Fn,
+ pub paren_token: tokens::Paren,
+ pub inputs: Delimited<BareFnArg, tokens::Comma>,
+ pub variadic: Option<tokens::Dot3>,
pub output: FunctionRetTy,
- pub variadic: bool,
}
}
ast_enum! {
#[cfg_attr(feature = "clone-impls", derive(Copy))]
pub enum Unsafety {
- Unsafe,
+ Unsafe(tokens::Unsafe),
Normal,
}
}
+ast_struct! {
+ pub struct Abi {
+ pub extern_token: tokens::Extern,
+ pub kind: AbiKind,
+ }
+}
+
ast_enum! {
- pub enum Abi {
- Named(String),
- Rust,
+ pub enum AbiKind {
+ Named(Lit),
+ Default,
}
}
@@ -253,7 +292,7 @@
///
/// E.g. `bar: usize` as in `fn foo(bar: usize)`
pub struct BareFnArg {
- pub name: Option<Ident>,
+ pub name: Option<(Ident, tokens::Colon)>,
pub ty: Ty,
}
}
@@ -268,7 +307,7 @@
/// type would be inserted.
Default,
/// Everything else
- Ty(Ty),
+ Ty(Ty, tokens::RArrow),
}
}
@@ -282,9 +321,9 @@
use constant::parsing::const_expr;
#[cfg(feature = "full")]
use expr::parsing::expr;
- use generics::parsing::{lifetime, lifetime_def, ty_param_bound, bound_lifetimes};
+ use generics::parsing::{lifetime, ty_param_bound, bound_lifetimes};
use ident::parsing::ident;
- use lit::parsing::quoted_string;
+ use lit::parsing::string;
use mac::parsing::mac;
use std::str;
@@ -320,7 +359,10 @@
punct!("[") >>
elem: ty >>
punct!("]") >>
- (TySlice { ty: Box::new(elem) }.into())
+ (TySlice {
+ ty: Box::new(elem),
+ bracket_token: tokens::Bracket::default(),
+ }.into())
));
named!(ty_array -> Ty, do_parse!(
@@ -329,7 +371,12 @@
punct!(";") >>
len: array_len >>
punct!("]") >>
- (TyArray { ty: Box::new(elem), amt: len }.into())
+ (TyArray {
+ ty: Box::new(elem),
+ amt: len,
+ bracket_token: tokens::Bracket::default(),
+ semi_token: tokens::Semi::default(),
+ }.into())
));
#[cfg(not(feature = "full"))]
@@ -350,10 +397,15 @@
mutability: alt!(
keyword!("const") => { |_| Mutability::Immutable }
|
- keyword!("mut") => { |_| Mutability::Mutable }
+ keyword!("mut") => { |_| Mutability::Mutable(tokens::Mut::default()) }
) >>
target: ty >>
(TyPtr {
+ const_token: match mutability {
+ Mutability::Mutable(_) => None,
+ Mutability::Immutable => Some(tokens::Const::default()),
+ },
+ star_token: tokens::Star::default(),
ty: Box::new(MutTy {
ty: target,
mutability: mutability,
@@ -372,97 +424,113 @@
ty: target,
mutability: mutability,
}),
+ and_token: tokens::And::default(),
}.into())
));
named!(ty_bare_fn -> Ty, do_parse!(
- lifetimes: opt_vec!(do_parse!(
- keyword!("for") >>
- punct!("<") >>
- lifetimes: terminated_list!(punct!(","), lifetime_def) >>
- punct!(">") >>
- (lifetimes)
- )) >>
+ lifetimes: bound_lifetimes >>
unsafety: unsafety >>
abi: option!(abi) >>
keyword!("fn") >>
punct!("(") >>
- inputs: separated_list!(punct!(","), fn_arg) >>
- trailing_comma: option!(punct!(",")) >>
- variadic: option!(cond_reduce!(trailing_comma.is_some(), punct!("..."))) >>
+ inputs: terminated_list!(map!(punct!(","), |_| tokens::Comma::default()),
+ fn_arg) >>
+ variadic: option!(cond_reduce!(inputs.is_empty() || inputs.trailing_delim(),
+ punct!("..."))) >>
punct!(")") >>
- output: option!(preceded!(
- punct!("->"),
- ty
- )) >>
+ output: fn_ret_ty >>
(TyBareFn {
ty: Box::new(BareFnTy {
unsafety: unsafety,
abi: abi,
lifetimes: lifetimes,
inputs: inputs,
- output: match output {
- Some(ty) => FunctionRetTy::Ty(ty),
- None => FunctionRetTy::Default,
- },
- variadic: variadic.is_some(),
+ output: output,
+ variadic: variadic.map(|_| tokens::Dot3::default()),
+ fn_token: tokens::Fn::default(),
+ paren_token: tokens::Paren::default(),
}),
}.into())
));
- named!(ty_never -> Ty, map!(punct!("!"), |_| TyNever {}.into()));
+ named!(ty_never -> Ty, map!(punct!("!"), |_| TyNever {
+ bang_token: tokens::Bang::default(),
+ }.into()));
named!(ty_tup -> Ty, do_parse!(
punct!("(") >>
- elems: terminated_list!(punct!(","), ty) >>
+ elems: terminated_list!(map!(punct!(","), |_| tokens::Comma::default()),
+ ty) >>
punct!(")") >>
- (TyTup { tys: elems }.into())
+ (TyTup {
+ tys: elems,
+ paren_token: tokens::Paren::default(),
+ lone_comma: None, // TODO: does this just not parse?
+ }.into())
));
named!(ty_path -> Ty, do_parse!(
qpath: qpath >>
parenthesized: cond!(
- qpath.1.segments.last().unwrap().parameters.is_empty(),
+ qpath.1.segments.get(qpath.1.segments.len() - 1).item().parameters.is_empty(),
option!(parenthesized_parameter_data)
) >>
bounds: many0!(preceded!(punct!("+"), ty_param_bound)) >>
({
let (qself, mut path) = qpath;
if let Some(Some(parenthesized)) = parenthesized {
- path.segments.last_mut().unwrap().parameters = parenthesized;
+ let len = path.segments.len();
+ path.segments.get_mut(len - 1).item_mut().parameters = parenthesized;
}
if bounds.is_empty() {
TyPath { qself: qself, path: path }.into()
} else {
let path = TyParamBound::Trait(
PolyTraitRef {
- bound_lifetimes: Vec::new(),
+ bound_lifetimes: None,
trait_ref: path,
},
TraitBoundModifier::None,
);
- let bounds = Some(path).into_iter().chain(bounds).collect();
- TyTraitObject { bounds: bounds }.into()
+ let mut new_bounds = Delimited::new();
+ new_bounds.push_first(path);
+ for bound in bounds {
+ new_bounds.push_default(bound);
+ }
+ TyTraitObject { bounds: new_bounds }.into()
}
})
));
named!(parenthesized_parameter_data -> PathParameters, do_parse!(
punct!("(") >>
- inputs: terminated_list!(punct!(","), ty) >>
+ inputs: terminated_list!(map!(punct!(","), |_| tokens::Comma::default()),
+ ty) >>
punct!(")") >>
- output: option!(preceded!(
- punct!("->"),
- ty
- )) >>
+ output: fn_ret_ty >>
(PathParameters::Parenthesized(
ParenthesizedParameterData {
+ paren_token: tokens::Paren::default(),
inputs: inputs,
output: output,
},
))
));
+ named!(pub fn_ret_ty -> FunctionRetTy, map!(
+ option!(preceded!(
+ punct!("->"),
+ ty
+ )),
+ |ty| {
+ match ty {
+ Some(ty) => FunctionRetTy::Ty(ty, tokens::RArrow::default()),
+ None => FunctionRetTy::Default,
+ }
+ }
+ ));
+
named!(pub qpath -> (Option<QSelf>, Path), alt!(
map!(path, |p| (None, p))
|
@@ -475,21 +543,38 @@
)) >>
punct!(">") >>
punct!("::") >>
- rest: separated_nonempty_list!(punct!("::"), path_segment) >>
+ rest: separated_nonempty_list!(
+ map!(punct!("::"), |_| tokens::Colon2::default()),
+ path_segment
+ ) >>
({
- match path {
+ let as_token = path.as_ref().map(|_| tokens::As::default());
+ let (pos, path) = match path {
Some(mut path) => {
let pos = path.segments.len();
- path.segments.extend(rest);
- (Some(QSelf { ty: this, position: pos }), path)
+ if !path.segments.is_empty() && !path.segments.trailing_delim() {
+ path.segments.push_trailing(tokens::Colon2::default());
+ }
+ for item in rest.into_iter() {
+ path.segments.push(item);
+ }
+ (pos, path)
}
None => {
- (Some(QSelf { ty: this, position: 0 }), Path {
+ (0, Path {
+ leading_colon: None,
global: false,
segments: rest,
})
}
- }
+ };
+ (Some(QSelf {
+ ty: this,
+ position: pos,
+ gt_token: tokens::Gt::default(),
+ lt_token: tokens::Lt::default(),
+ as_token: as_token,
+ }), path)
})
)
|
@@ -497,35 +582,45 @@
));
named!(ty_poly_trait_ref -> Ty, map!(
- separated_nonempty_list!(punct!("+"), ty_param_bound),
+ separated_nonempty_list!(map!(punct!("+"), |_| tokens::Add::default()),
+ ty_param_bound),
|x| TyTraitObject { bounds: x }.into()
));
named!(ty_impl_trait -> Ty, do_parse!(
keyword!("impl") >>
- elem: separated_nonempty_list!(punct!("+"), ty_param_bound) >>
- (TyImplTrait { bounds: elem }.into())
+ elem: separated_nonempty_list!(map!(punct!("+"), |_| tokens::Add::default()),
+ ty_param_bound) >>
+ (TyImplTrait {
+ impl_token: tokens::Impl::default(),
+ bounds: elem,
+ }.into())
));
named!(ty_paren -> Ty, do_parse!(
punct!("(") >>
elem: ty >>
punct!(")") >>
- (TyParen { ty: Box::new(elem) }.into())
+ (TyParen {
+ paren_token: tokens::Paren::default(),
+ ty: Box::new(elem),
+ }.into())
));
named!(pub mutability -> Mutability, alt!(
- keyword!("mut") => { |_| Mutability::Mutable }
+ keyword!("mut") => { |_| Mutability::Mutable(tokens::Mut::default()) }
|
epsilon!() => { |_| Mutability::Immutable }
));
named!(pub path -> Path, do_parse!(
global: option!(punct!("::")) >>
- segments: separated_nonempty_list!(punct!("::"), path_segment) >>
+ segments: separated_nonempty_list!(map!(punct!("::"), |_| tokens::Colon2::default()),
+ path_segment) >>
(Path {
global: global.is_some(),
segments: segments,
+ leading_colon: global.map(|_| tokens::Colon2::default()),
})
));
@@ -533,27 +628,37 @@
do_parse!(
id: option!(ident) >>
punct!("<") >>
- lifetimes: separated_list!(punct!(","), lifetime) >>
- types: opt_vec!(preceded!(
- cond!(!lifetimes.is_empty(), punct!(",")),
- separated_nonempty_list!(
- punct!(","),
+ lifetimes: terminated_list!(
+ map!(punct!(","), |_| tokens::Comma::default()),
+ lifetime
+ ) >>
+ types: cond!(
+ lifetimes.is_empty() || lifetimes.trailing_delim(),
+ terminated_list!(
+ map!(punct!(","), |_| tokens::Comma::default()),
terminated!(ty, not!(punct!("=")))
)
- )) >>
- bindings: opt_vec!(preceded!(
- cond!(!lifetimes.is_empty() || !types.is_empty(), punct!(",")),
- separated_nonempty_list!(punct!(","), type_binding)
- )) >>
- cond!(!lifetimes.is_empty() || !types.is_empty() || !bindings.is_empty(), option!(punct!(","))) >>
+ ) >>
+ bindings: cond!(
+ match types {
+ Some(ref t) => t.is_empty() || t.trailing_delim(),
+ None => lifetimes.is_empty() || lifetimes.trailing_delim(),
+ },
+ terminated_list!(
+ map!(punct!(","), |_| tokens::Comma::default()),
+ type_binding
+ )
+ ) >>
punct!(">") >>
(PathSegment {
ident: id.unwrap_or_else(|| "".into()),
parameters: PathParameters::AngleBracketed(
AngleBracketedParameterData {
+ gt_token: Some(tokens::Gt::default()),
+ lt_token: Some(tokens::Lt::default()),
lifetimes: lifetimes,
- types: types,
- bindings: bindings,
+ types: types.unwrap_or_default(),
+ bindings: bindings.unwrap_or_default(),
}
),
})
@@ -572,10 +677,12 @@
named!(pub mod_style_path -> Path, do_parse!(
global: option!(punct!("::")) >>
- segments: separated_nonempty_list!(punct!("::"), mod_style_path_segment) >>
+ segments: separated_nonempty_list!(map!(punct!("::"), |_| tokens::Colon2::default()),
+ mod_style_path_segment) >>
(Path {
global: global.is_some(),
segments: segments,
+ leading_colon: global.map(|_| tokens::Colon2::default()),
})
));
@@ -597,6 +704,7 @@
ty: ty >>
(TypeBinding {
ident: id,
+ eq_token: tokens::Eq::default(),
ty: ty,
})
));
@@ -605,13 +713,14 @@
bound_lifetimes: bound_lifetimes >>
trait_ref: path >>
parenthesized: option!(cond_reduce!(
- trait_ref.segments.last().unwrap().parameters.is_empty(),
+ trait_ref.segments.get(trait_ref.segments.len() - 1).item().parameters.is_empty(),
parenthesized_parameter_data
)) >>
({
let mut trait_ref = trait_ref;
if let Some(parenthesized) = parenthesized {
- trait_ref.segments.last_mut().unwrap().parameters = parenthesized;
+ let len = trait_ref.segments.len();
+ trait_ref.segments.get_mut(len - 1).item_mut().parameters = parenthesized;
}
PolyTraitRef {
bound_lifetimes: bound_lifetimes,
@@ -629,23 +738,26 @@
)) >>
ty: ty >>
(BareFnArg {
- name: name,
+ name: name.map(|t| (t, tokens::Colon::default())),
ty: ty,
})
));
named!(pub unsafety -> Unsafety, alt!(
- keyword!("unsafe") => { |_| Unsafety::Unsafe }
+ keyword!("unsafe") => { |_| Unsafety::Unsafe(tokens::Unsafe::default()) }
|
epsilon!() => { |_| Unsafety::Normal }
));
named!(pub abi -> Abi, do_parse!(
keyword!("extern") >>
- name: option!(quoted_string) >>
- (match name {
- Some(name) => Abi::Named(name),
- None => Abi::Rust,
+ name: option!(string) >>
+ (Abi {
+ extern_token: tokens::Extern::default(),
+ kind: match name {
+ Some(name) => AbiKind::Named(name),
+ None => AbiKind::Default,
+ },
})
));
}
@@ -657,41 +769,36 @@
impl ToTokens for TySlice {
fn to_tokens(&self, tokens: &mut Tokens) {
- tokens.append("[");
- self.ty.to_tokens(tokens);
- tokens.append("]");
+ self.bracket_token.surround(tokens, |tokens| {
+ self.ty.to_tokens(tokens);
+ });
}
}
impl ToTokens for TyArray {
fn to_tokens(&self, tokens: &mut Tokens) {
- tokens.append("[");
- self.ty.to_tokens(tokens);
- tokens.append(";");
- self.amt.to_tokens(tokens);
- tokens.append("]");
+ self.bracket_token.surround(tokens, |tokens| {
+ self.ty.to_tokens(tokens);
+ self.semi_token.to_tokens(tokens);
+ self.amt.to_tokens(tokens);
+ });
}
}
impl ToTokens for TyPtr {
fn to_tokens(&self, tokens: &mut Tokens) {
- tokens.append("*");
- match self.ty.mutability {
- Mutability::Mutable => tokens.append("mut"),
- Mutability::Immutable => tokens.append("const"),
- }
+ self.star_token.to_tokens(tokens);
+ self.const_token.to_tokens(tokens);
+ self.ty.mutability.to_tokens(tokens);
self.ty.ty.to_tokens(tokens);
}
}
impl ToTokens for TyRptr {
fn to_tokens(&self, tokens: &mut Tokens) {
- tokens.append("&");
+ self.and_token.to_tokens(tokens);
self.lifetime.to_tokens(tokens);
- match self.ty.mutability {
- Mutability::Mutable => tokens.append("mut"),
- Mutability::Immutable => {}
- }
+ self.ty.mutability.to_tokens(tokens);
self.ty.ty.to_tokens(tokens);
}
}
@@ -704,44 +811,52 @@
impl ToTokens for TyNever {
fn to_tokens(&self, tokens: &mut Tokens) {
- tokens.append("!");
+ self.bang_token.to_tokens(tokens);
}
}
impl ToTokens for TyTup {
fn to_tokens(&self, tokens: &mut Tokens) {
- tokens.append("(");
- tokens.append_separated(&self.tys, ",");
- if self.tys.len() == 1 {
- tokens.append(",");
- }
- tokens.append(")");
+ self.paren_token.surround(tokens, |tokens| {
+ self.tys.to_tokens(tokens);
+ self.lone_comma.to_tokens(tokens);
+ })
}
}
impl ToTokens for TyPath {
fn to_tokens(&self, tokens: &mut Tokens) {
- let qself = match self.qself {
+ PathTokens(&self.qself, &self.path).to_tokens(tokens);
+ }
+ }
+
+ impl<'a> ToTokens for PathTokens<'a> {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ let qself = match *self.0 {
Some(ref qself) => qself,
- None => return self.path.to_tokens(tokens),
+ None => return self.1.to_tokens(tokens),
};
- tokens.append("<");
+ qself.lt_token.to_tokens(tokens);
qself.ty.to_tokens(tokens);
if qself.position > 0 {
- tokens.append("as");
- for (i, segment) in self.path.segments
+ qself.as_token.to_tokens(tokens);
+ self.1.leading_colon.to_tokens(tokens);
+ for (i, segment) in self.1.segments
.iter()
.take(qself.position)
.enumerate() {
- if i > 0 || self.path.global {
- tokens.append("::");
+ if i == qself.position - 1 {
+ segment.item().to_tokens(tokens);
+ qself.gt_token.to_tokens(tokens);
+ segment.delimiter().to_tokens(tokens);
+ } else {
+ segment.to_tokens(tokens);
}
- segment.to_tokens(tokens);
}
+ } else {
+ qself.gt_token.to_tokens(tokens);
}
- tokens.append(">");
- for segment in self.path.segments.iter().skip(qself.position) {
- tokens.append("::");
+ for segment in self.1.segments.iter().skip(qself.position) {
segment.to_tokens(tokens);
}
}
@@ -749,59 +864,50 @@
impl ToTokens for TyTraitObject {
fn to_tokens(&self, tokens: &mut Tokens) {
- tokens.append_separated(&self.bounds, "+");
+ self.bounds.to_tokens(tokens);
}
}
impl ToTokens for TyImplTrait {
fn to_tokens(&self, tokens: &mut Tokens) {
- tokens.append("impl");
- tokens.append_separated(&self.bounds, "+");
+ self.impl_token.to_tokens(tokens);
+ self.bounds.to_tokens(tokens);
}
}
impl ToTokens for TyParen {
fn to_tokens(&self, tokens: &mut Tokens) {
- tokens.append("(");
- self.ty.to_tokens(tokens);
- tokens.append(")");
+ self.paren_token.surround(tokens, |tokens| {
+ self.ty.to_tokens(tokens);
+ });
}
}
impl ToTokens for TyInfer {
fn to_tokens(&self, tokens: &mut Tokens) {
- tokens.append("_");
+ self.underscore_token.to_tokens(tokens);
}
}
impl ToTokens for Mutability {
fn to_tokens(&self, tokens: &mut Tokens) {
- if let Mutability::Mutable = *self {
- tokens.append("mut");
+ if let Mutability::Mutable(ref t) = *self {
+ t.to_tokens(tokens);
}
}
}
impl ToTokens for Path {
fn to_tokens(&self, tokens: &mut Tokens) {
- for (i, segment) in self.segments.iter().enumerate() {
- if i > 0 || self.global {
- tokens.append("::");
- }
- segment.to_tokens(tokens);
- }
+ self.leading_colon.to_tokens(tokens);
+ self.segments.to_tokens(tokens);
}
}
impl ToTokens for PathSegment {
fn to_tokens(&self, tokens: &mut Tokens) {
self.ident.to_tokens(tokens);
- if self.ident.as_ref().is_empty() && self.parameters.is_empty() {
- tokens.append("<");
- tokens.append(">");
- } else {
- self.parameters.to_tokens(tokens);
- }
+ self.parameters.to_tokens(tokens);
}
}
@@ -820,106 +926,69 @@
impl ToTokens for AngleBracketedParameterData {
fn to_tokens(&self, tokens: &mut Tokens) {
- let has_lifetimes = !self.lifetimes.is_empty();
- let has_types = !self.types.is_empty();
- let has_bindings = !self.bindings.is_empty();
- if !has_lifetimes && !has_types && !has_bindings {
- return;
- }
-
- tokens.append("<");
-
- let mut first = true;
- for lifetime in &self.lifetimes {
- if !first {
- tokens.append(",");
- }
- lifetime.to_tokens(tokens);
- first = false;
- }
- for ty in &self.types {
- if !first {
- tokens.append(",");
- }
- ty.to_tokens(tokens);
- first = false;
- }
- for binding in &self.bindings {
- if !first {
- tokens.append(",");
- }
- binding.to_tokens(tokens);
- first = false;
- }
-
- tokens.append(">");
+ self.lt_token.to_tokens(tokens);
+ self.lifetimes.to_tokens(tokens);
+ self.types.to_tokens(tokens);
+ self.bindings.to_tokens(tokens);
+ self.gt_token.to_tokens(tokens);
}
}
impl ToTokens for TypeBinding {
fn to_tokens(&self, tokens: &mut Tokens) {
self.ident.to_tokens(tokens);
- tokens.append("=");
+ self.eq_token.to_tokens(tokens);
self.ty.to_tokens(tokens);
}
}
impl ToTokens for ParenthesizedParameterData {
fn to_tokens(&self, tokens: &mut Tokens) {
- tokens.append("(");
- tokens.append_separated(&self.inputs, ",");
- tokens.append(")");
- if let Some(ref output) = self.output {
- tokens.append("->");
- output.to_tokens(tokens);
+ self.paren_token.surround(tokens, |tokens| {
+ self.inputs.to_tokens(tokens);
+ });
+ self.output.to_tokens(tokens);
+ }
+ }
+
+ impl ToTokens for FunctionRetTy {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ match *self {
+ FunctionRetTy::Default => {}
+ FunctionRetTy::Ty(ref ty, ref arrow) => {
+ arrow.to_tokens(tokens);
+ ty.to_tokens(tokens);
+ }
}
}
}
impl ToTokens for PolyTraitRef {
fn to_tokens(&self, tokens: &mut Tokens) {
- if !self.bound_lifetimes.is_empty() {
- tokens.append("for");
- tokens.append("<");
- tokens.append_separated(&self.bound_lifetimes, ",");
- tokens.append(">");
- }
+ self.bound_lifetimes.to_tokens(tokens);
self.trait_ref.to_tokens(tokens);
}
}
impl ToTokens for BareFnTy {
fn to_tokens(&self, tokens: &mut Tokens) {
- if !self.lifetimes.is_empty() {
- tokens.append("for");
- tokens.append("<");
- tokens.append_separated(&self.lifetimes, ",");
- tokens.append(">");
- }
+ self.lifetimes.to_tokens(tokens);
self.unsafety.to_tokens(tokens);
self.abi.to_tokens(tokens);
- tokens.append("fn");
- tokens.append("(");
- tokens.append_separated(&self.inputs, ",");
- if self.variadic {
- if !self.inputs.is_empty() {
- tokens.append(",");
- }
- tokens.append("...");
- }
- tokens.append(")");
- if let FunctionRetTy::Ty(ref ty) = self.output {
- tokens.append("->");
- ty.to_tokens(tokens);
- }
+ self.fn_token.to_tokens(tokens);
+ self.paren_token.surround(tokens, |tokens| {
+ self.inputs.to_tokens(tokens);
+ self.variadic.to_tokens(tokens);
+ });
+ self.output.to_tokens(tokens);
}
}
impl ToTokens for BareFnArg {
fn to_tokens(&self, tokens: &mut Tokens) {
- if let Some(ref name) = self.name {
+ if let Some((ref name, ref colon)) = self.name {
name.to_tokens(tokens);
- tokens.append(":");
+ colon.to_tokens(tokens);
}
self.ty.to_tokens(tokens);
}
@@ -928,7 +997,7 @@
impl ToTokens for Unsafety {
fn to_tokens(&self, tokens: &mut Tokens) {
match *self {
- Unsafety::Unsafe => tokens.append("unsafe"),
+ Unsafety::Unsafe(ref t) => t.to_tokens(tokens),
Unsafety::Normal => {
// nothing
}
@@ -938,10 +1007,10 @@
impl ToTokens for Abi {
fn to_tokens(&self, tokens: &mut Tokens) {
- tokens.append("extern");
- match *self {
- Abi::Named(ref named) => named.to_tokens(tokens),
- Abi::Rust => {}
+ self.extern_token.to_tokens(tokens);
+ match self.kind {
+ AbiKind::Named(ref named) => named.to_tokens(tokens),
+ AbiKind::Default => {}
}
}
}
diff --git a/src/visit.rs b/src/visit.rs
index c2b6d53..df49e71 100644
--- a/src/visit.rs
+++ b/src/visit.rs
@@ -147,13 +147,15 @@
pub fn walk_lifetime_def<V: Visitor>(visitor: &mut V, lifetime_def: &LifetimeDef) {
visitor.visit_lifetime(&lifetime_def.lifetime);
- walk_list!(visitor, visit_lifetime, &lifetime_def.bounds);
+ walk_list!(visitor, visit_lifetime, lifetime_def.bounds.items());
}
pub fn walk_poly_trait_ref<V>(visitor: &mut V, trait_ref: &PolyTraitRef, _: &TraitBoundModifier)
where V: Visitor
{
- walk_list!(visitor, visit_lifetime_def, &trait_ref.bound_lifetimes);
+ if let Some(ref bl) = trait_ref.bound_lifetimes {
+ walk_list!(visitor, visit_lifetime_def, bl.lifetimes.items());
+ }
visitor.visit_path(&trait_ref.trait_ref);
}
@@ -161,11 +163,13 @@
visitor.visit_ident(&derive_input.ident);
visitor.visit_generics(&derive_input.generics);
match derive_input.body {
- Body::Enum(ref variants) => {
- walk_list!(visitor, visit_variant, variants, &derive_input.generics);
+ Body::Enum(ref data) => {
+ walk_list!(visitor, visit_variant,
+ data.variants.items(),
+ &derive_input.generics);
}
- Body::Struct(ref variant_data) => {
- visitor.visit_variant_data(variant_data, &derive_input.ident, &derive_input.generics);
+ Body::Struct(ref data) => {
+ visitor.visit_variant_data(&data.data, &derive_input.ident, &derive_input.generics);
}
}
walk_list!(visitor, visit_attribute, &derive_input.attrs);
@@ -183,21 +187,25 @@
use ty::*;
match *ty {
- Ty::Slice(TySlice { ref ty }) |
- Ty::Paren(TyParen { ref ty }) => visitor.visit_ty(ty),
- Ty::Ptr(TyPtr { ref ty }) => visitor.visit_ty(&ty.ty),
- Ty::Rptr(TyRptr { ref lifetime, ref ty }) => {
+ Ty::Slice(TySlice { ref ty, .. }) |
+ Ty::Paren(TyParen { ref ty, .. }) => visitor.visit_ty(ty),
+ Ty::Ptr(TyPtr { ref ty, .. }) => visitor.visit_ty(&ty.ty),
+ Ty::Rptr(TyRptr { ref lifetime, ref ty, .. }) => {
walk_list!(visitor, visit_lifetime, lifetime);
visitor.visit_ty(&ty.ty)
}
Ty::Never(_) | Ty::Infer(_) => {}
- Ty::Tup(TyTup { ref tys }) => {
- walk_list!(visitor, visit_ty, tys);
+ Ty::Tup(TyTup { ref tys, .. }) => {
+ walk_list!(visitor, visit_ty, tys.items());
}
Ty::BareFn(TyBareFn { ref ty }) => {
- walk_list!(visitor, visit_lifetime_def, &ty.lifetimes);
- for argument in &ty.inputs {
- walk_opt_ident(visitor, &argument.name);
+ if let Some(ref l) = ty.lifetimes {
+ walk_list!(visitor, visit_lifetime_def, l.lifetimes.items());
+ }
+ for argument in ty.inputs.items() {
+ if let Some((ref name, _)) = argument.name {
+ visitor.visit_ident(name);
+ }
visitor.visit_ty(&argument.ty)
}
visitor.visit_fn_ret_ty(&ty.output)
@@ -208,13 +216,13 @@
}
visitor.visit_path(path);
}
- Ty::Array(TyArray { ref ty, ref amt }) => {
+ Ty::Array(TyArray { ref ty, ref amt, .. }) => {
visitor.visit_ty(ty);
visitor.visit_const_expr(amt);
}
- Ty::TraitObject(TyTraitObject { ref bounds }) |
- Ty::ImplTrait(TyImplTrait { ref bounds }) => {
- walk_list!(visitor, visit_ty_param_bound, bounds);
+ Ty::TraitObject(TyTraitObject { ref bounds, .. }) |
+ Ty::ImplTrait(TyImplTrait { ref bounds, .. }) => {
+ walk_list!(visitor, visit_ty_param_bound, bounds.items());
}
Ty::Mac(ref mac) => {
visitor.visit_mac(mac);
@@ -223,7 +231,7 @@
}
pub fn walk_path<V: Visitor>(visitor: &mut V, path: &Path) {
- for segment in &path.segments {
+ for segment in path.segments.items() {
visitor.visit_path_segment(segment);
}
}
@@ -238,13 +246,13 @@
{
match *path_parameters {
PathParameters::AngleBracketed(ref data) => {
- walk_list!(visitor, visit_ty, &data.types);
- walk_list!(visitor, visit_lifetime, &data.lifetimes);
- walk_list!(visitor, visit_assoc_type_binding, &data.bindings);
+ walk_list!(visitor, visit_ty, data.types.items());
+ walk_list!(visitor, visit_lifetime, data.lifetimes.items());
+ walk_list!(visitor, visit_assoc_type_binding, data.bindings.items());
}
PathParameters::Parenthesized(ref data) => {
- walk_list!(visitor, visit_ty, &data.inputs);
- walk_list!(visitor, visit_ty, &data.output);
+ walk_list!(visitor, visit_ty, data.inputs.items());
+ visitor.visit_fn_ret_ty(&data.output);
}
}
}
@@ -266,27 +274,29 @@
}
pub fn walk_generics<V: Visitor>(visitor: &mut V, generics: &Generics) {
- for param in &generics.ty_params {
+ for param in generics.ty_params.items() {
visitor.visit_ident(¶m.ident);
- walk_list!(visitor, visit_ty_param_bound, ¶m.bounds);
+ walk_list!(visitor, visit_ty_param_bound, param.bounds.items());
walk_list!(visitor, visit_ty, ¶m.default);
}
- walk_list!(visitor, visit_lifetime_def, &generics.lifetimes);
- for predicate in &generics.where_clause.predicates {
+ walk_list!(visitor, visit_lifetime_def, generics.lifetimes.items());
+ for predicate in generics.where_clause.predicates.items() {
match *predicate {
WherePredicate::BoundPredicate(WhereBoundPredicate { ref bounded_ty,
ref bounds,
ref bound_lifetimes,
.. }) => {
visitor.visit_ty(bounded_ty);
- walk_list!(visitor, visit_ty_param_bound, bounds);
- walk_list!(visitor, visit_lifetime_def, bound_lifetimes);
+ walk_list!(visitor, visit_ty_param_bound, bounds.items());
+ if let Some(ref l) = *bound_lifetimes {
+ walk_list!(visitor, visit_lifetime_def, l.lifetimes.items());
+ }
}
WherePredicate::RegionPredicate(WhereRegionPredicate { ref lifetime,
ref bounds,
.. }) => {
visitor.visit_lifetime(lifetime);
- walk_list!(visitor, visit_lifetime, bounds);
+ walk_list!(visitor, visit_lifetime, bounds.items());
}
WherePredicate::EqPredicate(WhereEqPredicate { ref lhs_ty, ref rhs_ty, .. }) => {
visitor.visit_ty(lhs_ty);
@@ -297,13 +307,18 @@
}
pub fn walk_fn_ret_ty<V: Visitor>(visitor: &mut V, ret_ty: &FunctionRetTy) {
- if let FunctionRetTy::Ty(ref output_ty) = *ret_ty {
+ if let FunctionRetTy::Ty(ref output_ty, _) = *ret_ty {
visitor.visit_ty(output_ty)
}
}
pub fn walk_variant_data<V: Visitor>(visitor: &mut V, data: &VariantData) {
- walk_list!(visitor, visit_field, data.fields());
+ let fields = match *data {
+ VariantData::Struct(ref f, _) |
+ VariantData::Tuple(ref f, _) => f,
+ VariantData::Unit => return,
+ };
+ walk_list!(visitor, visit_field, fields.items());
}
pub fn walk_field<V: Visitor>(visitor: &mut V, field: &Field) {
@@ -317,9 +332,9 @@
use constant::ConstExpr::*;
match *len {
- Call(ConstCall { ref func, ref args }) => {
+ Call(ConstCall { ref func, ref args, .. }) => {
visitor.visit_const_expr(func);
- walk_list!(visitor, visit_const_expr, args);
+ walk_list!(visitor, visit_const_expr, args.items());
}
Binary(ConstBinary { ref left, ref right, .. }) => {
visitor.visit_const_expr(left);
@@ -328,19 +343,19 @@
Lit(ref lit) => {
visitor.visit_lit(lit);
}
- Cast(ConstCast { ref expr, ref ty }) => {
+ Cast(ConstCast { ref expr, ref ty, .. }) => {
visitor.visit_const_expr(expr);
visitor.visit_ty(ty);
}
Path(ref path) => {
visitor.visit_path(path);
}
- Index(ConstIndex { ref expr, ref index }) => {
+ Index(ConstIndex { ref expr, ref index, .. }) => {
visitor.visit_const_expr(expr);
visitor.visit_const_expr(index);
}
Unary(ConstUnary { ref expr, .. }) |
- Paren(ConstParen { ref expr }) => {
+ Paren(ConstParen { ref expr, .. }) => {
visitor.visit_const_expr(expr);
}
Other(ref other) => {
@@ -372,39 +387,38 @@
visitor.visit_ident(&item.ident);
walk_list!(visitor, visit_attribute, &item.attrs);
match item.node {
- ItemKind::ExternCrate(ItemExternCrate { ref original }) => {
+ ItemKind::ExternCrate(ItemExternCrate { ref original, .. }) => {
walk_opt_ident(visitor, original);
}
- ItemKind::Use(ItemUse { ref path }) => {
+ ItemKind::Use(ItemUse { ref path, .. }) => {
visitor.visit_view_path(path);
}
ItemKind::Static(ItemStatic { ref ty, ref expr, .. }) |
- ItemKind::Const(ItemConst { ref ty, ref expr }) => {
+ ItemKind::Const(ItemConst { ref ty, ref expr, .. }) => {
visitor.visit_ty(ty);
visitor.visit_expr(expr);
}
- ItemKind::Fn(ItemFn { ref decl, ref generics, ref block, .. }) => {
+ ItemKind::Fn(ItemFn { ref decl, ref block, .. }) => {
visitor.visit_fn_decl(decl);
- visitor.visit_generics(generics);
walk_list!(visitor, visit_stmt, &block.stmts);
}
- ItemKind::Mod(ItemMod { ref items }) => {
- if let Some(ref items) = *items {
+ ItemKind::Mod(ItemMod { ref items, .. }) => {
+ if let Some((ref items, _)) = *items {
walk_list!(visitor, visit_item, items);
}
}
ItemKind::ForeignMod(ItemForeignMod { ref items, .. }) => {
walk_list!(visitor, visit_foreign_item, items);
}
- ItemKind::Ty(ItemTy { ref ty, ref generics }) => {
+ ItemKind::Ty(ItemTy { ref ty, ref generics, .. }) => {
visitor.visit_ty(ty);
visitor.visit_generics(generics);
}
- ItemKind::Enum(ItemEnum { ref variants, ref generics }) => {
- walk_list!(visitor, visit_variant, variants, generics);
+ ItemKind::Enum(ItemEnum { ref variants, ref generics, ..}) => {
+ walk_list!(visitor, visit_variant, variants.items(), generics);
}
- ItemKind::Struct(ItemStruct { ref data, ref generics }) |
- ItemKind::Union(ItemUnion { ref data, ref generics }) => {
+ ItemKind::Struct(ItemStruct { ref data, ref generics, .. }) |
+ ItemKind::Union(ItemUnion { ref data, ref generics, .. }) => {
visitor.visit_variant_data(data, &item.ident, generics);
}
ItemKind::Trait(ItemTrait {
@@ -414,7 +428,7 @@
..
}) => {
visitor.visit_generics(generics);
- walk_list!(visitor, visit_ty_param_bound, supertraits);
+ walk_list!(visitor, visit_ty_param_bound, supertraits.items());
walk_list!(visitor, visit_trait_item, items);
}
ItemKind::DefaultImpl(ItemDefaultImpl { ref path, .. }) => {
@@ -446,39 +460,39 @@
walk_list!(visitor, visit_attribute, &expr.attrs);
match expr.node {
- InPlace(ExprInPlace { ref place, ref value }) => {
+ InPlace(ExprInPlace { ref place, ref value, .. }) => {
visitor.visit_expr(place);
visitor.visit_expr(value);
}
- Call(ExprCall { ref func, ref args }) => {
+ Call(ExprCall { ref func, ref args, .. }) => {
visitor.visit_expr(func);
- walk_list!(visitor, visit_expr, args);
+ walk_list!(visitor, visit_expr, args.items());
}
- MethodCall(ExprMethodCall { ref method, ref typarams, ref args }) => {
+ MethodCall(ExprMethodCall { ref method, ref typarams, ref args, .. }) => {
visitor.visit_ident(method);
- walk_list!(visitor, visit_ty, typarams);
- walk_list!(visitor, visit_expr, args);
+ walk_list!(visitor, visit_ty, typarams.items());
+ walk_list!(visitor, visit_expr, args.items());
}
- Array(ExprArray { ref exprs }) |
- Tup(ExprTup { args: ref exprs }) => {
- walk_list!(visitor, visit_expr, exprs);
+ Array(ExprArray { ref exprs, ..}) |
+ Tup(ExprTup { args: ref exprs, .. }) => {
+ walk_list!(visitor, visit_expr, exprs.items());
}
Lit(ref lit) => {
visitor.visit_lit(lit);
}
- Cast(ExprCast { ref expr, ref ty }) |
- Type(ExprType { ref expr, ref ty }) => {
+ Cast(ExprCast { ref expr, ref ty, .. }) |
+ Type(ExprType { ref expr, ref ty, .. }) => {
visitor.visit_expr(expr);
visitor.visit_ty(ty);
}
- If(ExprIf { ref cond, ref if_true, ref if_false }) => {
+ If(ExprIf { ref cond, ref if_true, ref if_false, .. }) => {
visitor.visit_expr(cond);
walk_list!(visitor, visit_stmt, &if_true.stmts);
if let Some(ref alt) = *if_false {
visitor.visit_expr(alt);
}
}
- IfLet(ExprIfLet { ref pat, ref expr, ref if_true, ref if_false }) => {
+ IfLet(ExprIfLet { ref pat, ref expr, ref if_true, ref if_false, .. }) => {
visitor.visit_pat(pat);
visitor.visit_expr(expr);
walk_list!(visitor, visit_stmt, &if_true.stmts);
@@ -486,27 +500,27 @@
visitor.visit_expr(alt);
}
}
- While(ExprWhile { ref cond, ref body, ref label }) => {
+ While(ExprWhile { ref cond, ref body, ref label, .. }) => {
visitor.visit_expr(cond);
walk_list!(visitor, visit_stmt, &body.stmts);
walk_opt_ident(visitor, label);
}
- WhileLet(ExprWhileLet { ref pat, ref expr, ref body, ref label }) |
- ForLoop(ExprForLoop { ref pat, ref expr, ref body, ref label }) => {
+ WhileLet(ExprWhileLet { ref pat, ref expr, ref body, ref label, .. }) |
+ ForLoop(ExprForLoop { ref pat, ref expr, ref body, ref label, .. }) => {
visitor.visit_pat(pat);
visitor.visit_expr(expr);
walk_list!(visitor, visit_stmt, &body.stmts);
walk_opt_ident(visitor, label);
}
- Loop(ExprLoop { ref body, ref label }) => {
+ Loop(ExprLoop { ref body, ref label, .. }) => {
walk_list!(visitor, visit_stmt, &body.stmts);
walk_opt_ident(visitor, label);
}
- Match(ExprMatch { ref expr, ref arms }) => {
+ Match(ExprMatch { ref expr, ref arms, .. }) => {
visitor.visit_expr(expr);
- for &Arm { ref attrs, ref pats, ref guard, ref body } in arms {
+ for &Arm { ref attrs, ref pats, ref guard, ref body, .. } in arms {
walk_list!(visitor, visit_attribute, attrs);
- walk_list!(visitor, visit_pat, pats);
+ walk_list!(visitor, visit_pat, pats.items());
if let Some(ref guard) = *guard {
visitor.visit_expr(guard);
}
@@ -517,21 +531,21 @@
visitor.visit_fn_decl(decl);
visitor.visit_expr(body);
}
- Catch(ExprCatch { ref block }) |
+ Catch(ExprCatch { ref block, .. }) |
Block(ExprBlock { ref block, .. }) => {
walk_list!(visitor, visit_stmt, &block.stmts);
}
Binary(ExprBinary { ref left, ref right, .. }) |
- Assign(ExprAssign { ref left, ref right }) |
+ Assign(ExprAssign { ref left, ref right, .. }) |
AssignOp(ExprAssignOp { ref left, ref right, .. }) => {
visitor.visit_expr(left);
visitor.visit_expr(right);
}
- Field(ExprField { ref expr, ref field }) => {
+ Field(ExprField { ref expr, ref field, .. }) => {
visitor.visit_expr(expr);
visitor.visit_ident(field);
}
- Index(ExprIndex { ref expr, ref index }) => {
+ Index(ExprIndex { ref expr, ref index, .. }) => {
visitor.visit_expr(expr);
visitor.visit_expr(index);
}
@@ -549,16 +563,16 @@
}
visitor.visit_path(path);
}
- Break(ExprBreak { ref label, ref expr }) => {
+ Break(ExprBreak { ref label, ref expr, .. }) => {
walk_opt_ident(visitor, label);
if let Some(ref expr) = *expr {
visitor.visit_expr(expr);
}
}
- Continue(ExprContinue { ref label }) => {
+ Continue(ExprContinue { ref label, .. }) => {
walk_opt_ident(visitor, label);
}
- Ret(ExprRet { ref expr }) => {
+ Ret(ExprRet { ref expr, .. }) => {
if let Some(ref expr) = *expr {
visitor.visit_expr(expr);
}
@@ -566,9 +580,9 @@
Mac(ref mac) => {
visitor.visit_mac(mac);
}
- Struct(ExprStruct { ref path, ref fields, ref rest }) => {
+ Struct(ExprStruct { ref path, ref fields, ref rest, .. }) => {
visitor.visit_path(path);
- for &FieldValue { ref ident, ref expr, .. } in fields {
+ for &FieldValue { ref ident, ref expr, .. } in fields.items() {
visitor.visit_ident(ident);
visitor.visit_expr(expr);
}
@@ -576,16 +590,16 @@
visitor.visit_expr(base);
}
}
- Repeat(ExprRepeat { ref expr, ref amt }) => {
+ Repeat(ExprRepeat { ref expr, ref amt, .. }) => {
visitor.visit_expr(expr);
visitor.visit_expr(amt);
}
TupField(ExprTupField { ref expr, .. }) |
Unary(ExprUnary { ref expr, .. }) |
- Box(ExprBox { ref expr }) |
+ Box(ExprBox { ref expr, .. }) |
AddrOf(ExprAddrOf { ref expr, .. }) |
- Paren(ExprParen { ref expr }) |
- Try(ExprTry { ref expr }) => {
+ Paren(ExprParen { ref expr, .. }) |
+ Try(ExprTry { ref expr, .. }) => {
visitor.visit_expr(expr);
}
}
@@ -598,9 +612,8 @@
visitor.visit_ident(&foreign_item.ident);
walk_list!(visitor, visit_attribute, &foreign_item.attrs);
match foreign_item.node {
- ForeignItemKind::Fn(ForeignItemFn { ref decl, ref generics }) => {
+ ForeignItemKind::Fn(ForeignItemFn { ref decl, .. }) => {
visitor.visit_fn_decl(decl);
- visitor.visit_generics(generics);
}
ForeignItemKind::Static(ForeignItemStatic { ref ty, .. }) => {
visitor.visit_ty(ty);
@@ -610,51 +623,53 @@
#[cfg(feature = "full")]
pub fn walk_pat<V: Visitor>(visitor: &mut V, pat: &Pat) {
+ use expr::*;
+
match *pat {
- Pat::Wild => {}
- Pat::Ident(_, ref ident, ref maybe_pat) => {
+ Pat::Wild(_) => {}
+ Pat::Ident(PatIdent { ref ident, ref subpat, .. }) => {
visitor.visit_ident(ident);
- if let Some(ref pat) = *maybe_pat {
+ if let Some(ref pat) = *subpat {
visitor.visit_pat(pat);
}
}
- Pat::Struct(ref path, ref field_pats, _) => {
+ Pat::Struct(PatStruct { ref path, ref fields, .. }) => {
visitor.visit_path(path);
- for &FieldPat { ref ident, ref pat, .. } in field_pats {
+ for &FieldPat { ref ident, ref pat, .. } in fields.items() {
visitor.visit_ident(ident);
visitor.visit_pat(pat);
}
}
- Pat::TupleStruct(ref path, ref pats, _) => {
+ Pat::TupleStruct(PatTupleStruct { ref path, ref pat, .. }) => {
visitor.visit_path(path);
- walk_list!(visitor, visit_pat, pats);
+ walk_list!(visitor, visit_pat, pat.pats.items());
}
- Pat::Path(ref maybe_qself, ref path) => {
- if let Some(ref qself) = *maybe_qself {
+ Pat::Path(PatPath { ref qself, ref path }) => {
+ if let Some(ref qself) = *qself {
visitor.visit_ty(&qself.ty);
}
visitor.visit_path(path);
}
- Pat::Tuple(ref pats, _) => {
- walk_list!(visitor, visit_pat, pats);
+ Pat::Tuple(PatTuple { ref pats, .. }) => {
+ walk_list!(visitor, visit_pat, pats.items());
}
- Pat::Box(ref pat) |
- Pat::Ref(ref pat, _) => {
+ Pat::Box(PatBox { ref pat, .. }) |
+ Pat::Ref(PatRef { ref pat, .. }) => {
visitor.visit_pat(pat);
}
- Pat::Lit(ref expr) => {
+ Pat::Lit(PatLit { ref expr }) => {
visitor.visit_expr(expr);
}
- Pat::Range(ref start, ref end, _) => {
- visitor.visit_expr(start);
- visitor.visit_expr(end);
+ Pat::Range(PatRange { ref lo, ref hi, .. }) => {
+ visitor.visit_expr(lo);
+ visitor.visit_expr(hi);
}
- Pat::Slice(ref start, ref maybe_mid, ref end) => {
- walk_list!(visitor, visit_pat, start);
- if let Some(ref mid) = *maybe_mid {
+ Pat::Slice(PatSlice { ref front, ref middle, ref back, .. }) => {
+ walk_list!(visitor, visit_pat, front.items());
+ if let Some(ref mid) = *middle {
visitor.visit_pat(mid);
}
- walk_list!(visitor, visit_pat, end);
+ walk_list!(visitor, visit_pat, back.items());
}
Pat::Mac(ref mac) => {
visitor.visit_mac(mac);
@@ -666,11 +681,11 @@
pub fn walk_fn_decl<V: Visitor>(visitor: &mut V, fn_decl: &FnDecl) {
use item::*;
- for input in &fn_decl.inputs {
+ for input in fn_decl.inputs.items() {
match *input {
FnArg::SelfRef(_) |
FnArg::SelfValue(_) => {}
- FnArg::Captured(ArgCaptured { ref pat, ref ty }) => {
+ FnArg::Captured(ArgCaptured { ref pat, ref ty, .. }) => {
visitor.visit_pat(pat);
visitor.visit_ty(ty);
}
@@ -679,6 +694,7 @@
}
}
}
+ visitor.visit_generics(&fn_decl.generics);
visitor.visit_fn_ret_ty(&fn_decl.output);
}
@@ -689,20 +705,20 @@
visitor.visit_ident(&trait_item.ident);
walk_list!(visitor, visit_attribute, &trait_item.attrs);
match trait_item.node {
- TraitItemKind::Const(TraitItemConst { ref ty, ref default }) => {
+ TraitItemKind::Const(TraitItemConst { ref ty, ref default, ..}) => {
visitor.visit_ty(ty);
if let Some(ref expr) = *default {
visitor.visit_expr(expr);
}
}
- TraitItemKind::Method(TraitItemMethod { ref sig, ref default }) => {
+ TraitItemKind::Method(TraitItemMethod { ref sig, ref default, .. }) => {
visitor.visit_method_sig(sig);
if let Some(ref block) = *default {
walk_list!(visitor, visit_stmt, &block.stmts);
}
}
- TraitItemKind::Type(TraitItemType { ref bounds, ref default }) => {
- walk_list!(visitor, visit_ty_param_bound, bounds);
+ TraitItemKind::Type(TraitItemType { ref bounds, ref default, .. }) => {
+ walk_list!(visitor, visit_ty_param_bound, bounds.items());
if let Some(ref ty) = *default {
visitor.visit_ty(ty);
}
@@ -720,15 +736,15 @@
visitor.visit_ident(&impl_item.ident);
walk_list!(visitor, visit_attribute, &impl_item.attrs);
match impl_item.node {
- ImplItemKind::Const(ImplItemConst { ref ty, ref expr }) => {
+ ImplItemKind::Const(ImplItemConst { ref ty, ref expr, .. }) => {
visitor.visit_ty(ty);
visitor.visit_expr(expr);
}
- ImplItemKind::Method(ImplItemMethod { ref sig, ref block }) => {
+ ImplItemKind::Method(ImplItemMethod { ref sig, ref block, .. }) => {
visitor.visit_method_sig(sig);
walk_list!(visitor, visit_stmt, &block.stmts);
}
- ImplItemKind::Type(ImplItemType { ref ty }) => {
+ ImplItemKind::Type(ImplItemType { ref ty, .. }) => {
visitor.visit_ty(ty);
}
ImplItemKind::Macro(ref mac) => {
@@ -740,7 +756,6 @@
#[cfg(feature = "full")]
pub fn walk_method_sig<V: Visitor>(visitor: &mut V, method_sig: &MethodSig) {
visitor.visit_fn_decl(&method_sig.decl);
- visitor.visit_generics(&method_sig.generics);
}
#[cfg(feature = "full")]
@@ -753,7 +768,7 @@
visitor.visit_item(item);
}
Stmt::Expr(ref expr) |
- Stmt::Semi(ref expr) => {
+ Stmt::Semi(ref expr, _) => {
visitor.visit_expr(expr);
}
Stmt::Mac(ref details) => {
@@ -780,16 +795,16 @@
pub fn walk_view_path<V: Visitor>(visitor: &mut V, view_path: &ViewPath) {
use item::*;
match *view_path {
- ViewPath::Simple(PathSimple { ref path, ref rename }) => {
+ ViewPath::Simple(PathSimple { ref path, ref rename, .. }) => {
visitor.visit_path(path);
walk_opt_ident(visitor, rename);
}
- ViewPath::Glob(PathGlob { ref path }) => {
+ ViewPath::Glob(PathGlob { ref path, .. }) => {
visitor.visit_path(path);
}
- ViewPath::List(PathList { ref path, ref items }) => {
+ ViewPath::List(PathList { ref path, ref items, .. }) => {
visitor.visit_path(path);
- for &PathListItem { ref name, ref rename } in items {
+ for &PathListItem { ref name, ref rename, .. } in items.items() {
visitor.visit_ident(name);
walk_opt_ident(visitor, rename);
}