Rewrite the AST to be a bit more user-friendly
This commit is a relatively large rewrite of the AST that `syn` exposes. The
main change is to expose enums-of-structs rather than
enums-with-huge-tuple-variants. The best example of this is `ItemKind::Fn` which
changed from:
enum ItemKind {
Fn(Box<FnDecl>, Unsafety, Constness, Option<Abi>, Generics, Box<Block>),
...
}
to
enum ItemKind {
Fn(ItemFn),
...
}
struct ItemFn {
decl: Box<FnDecl>,
unsafety: Unsafety,
constness: Constness,
abi: Option<Abi>,
generics: Generics,
block: Box<Block>,
}
This change serves a few purposes:
* It's now much easier to add fields to each variant of the ast, ast struct
fields tend to be "by default ignored" in most contexts.
* It's much easier to document what each field is, as each field can have
dedicated documentation.
* There's now canonicalized names for each field (the name of the field) which
can help match `match` statements more consistent across a codebase.
A downside of this representation is that it can be a little more verbose to
work with in `match` statements and during constructions. Overall though I'd
feel at least that the readability improved significantly despite the extra
words required to do various operations.
Closes #136
diff --git a/src/aster/ty.rs b/src/aster/ty.rs
index 7dff3b4..f43e4a5 100644
--- a/src/aster/ty.rs
+++ b/src/aster/ty.rs
@@ -1,4 +1,5 @@
use {Generics, Lifetime, MutTy, Mutability, Path, QSelf, Ty, TyParamBound};
+use {TyPath, TySlice, TyNever, TyInfer, TyTup, TyRptr, TyImplTrait};
use aster::ident::ToIdent;
use aster::invoke::{Invoke, Identity};
use aster::lifetime::IntoLifetime;
@@ -36,11 +37,11 @@
}
pub fn build_path(self, path: Path) -> F::Result {
- self.build(Ty::Path(None, path))
+ self.build(Ty::Path(TyPath { qself: None, path: path }))
}
pub fn build_qpath(self, qself: QSelf, path: Path) -> F::Result {
- self.build(Ty::Path(Some(qself), path))
+ self.build(Ty::Path(TyPath { qself: Some(qself), path: path }))
}
pub fn path(self) -> PathBuilder<TyPathBuilder<F>> {
@@ -115,7 +116,7 @@
}
pub fn build_slice(self, ty: Ty) -> F::Result {
- self.build(Ty::Slice(Box::new(ty)))
+ self.build(Ty::Slice(TySlice { ty: Box::new(ty) }))
}
pub fn slice(self) -> TyBuilder<TySliceBuilder<F>> {
@@ -131,11 +132,11 @@
}
pub fn never(self) -> F::Result {
- self.build(Ty::Never)
+ self.build(Ty::Never(TyNever {}))
}
pub fn infer(self) -> F::Result {
- self.build(Ty::Infer)
+ self.build(Ty::Infer(TyInfer {}))
}
pub fn option(self) -> TyBuilder<TyOptionBuilder<F>> {
@@ -236,7 +237,10 @@
ty: ty,
mutability: self.mutability,
};
- self.builder.build(Ty::Rptr(self.lifetime, Box::new(ty)))
+ self.builder.build(Ty::Rptr(TyRptr {
+ lifetime: self.lifetime,
+ ty: Box::new(ty),
+ }))
}
pub fn ty(self) -> TyBuilder<Self> {
@@ -432,7 +436,9 @@
pub fn build(self) -> F::Result {
let bounds = self.bounds;
- self.builder.build(Ty::ImplTrait(bounds))
+ self.builder.build(Ty::ImplTrait(TyImplTrait {
+ bounds: bounds,
+ }))
}
}
@@ -473,7 +479,7 @@
}
pub fn build(self) -> F::Result {
- self.builder.build(Ty::Tup(self.tys))
+ self.builder.build(Ty::Tup(TyTup { tys: self.tys }))
}
}
diff --git a/src/attr.rs b/src/attr.rs
index 0a2b016..fecfd9a 100644
--- a/src/attr.rs
+++ b/src/attr.rs
@@ -2,24 +2,25 @@
use std::iter;
-/// Doc-comments are promoted to attributes that have `is_sugared_doc` = true
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-pub struct Attribute {
- pub style: AttrStyle,
+ast_struct! {
+ /// Doc-comments are promoted to attributes that have `is_sugared_doc` = true
+ pub struct Attribute {
+ pub style: AttrStyle,
- /// The path of the attribute.
- ///
- /// E.g. `derive` in `#[derive(Copy)]`
- /// E.g. `crate::precondition` in `#[crate::precondition x < 5]`
- pub path: Path,
+ /// The path of the attribute.
+ ///
+ /// E.g. `derive` in `#[derive(Copy)]`
+ /// E.g. `crate::precondition` in `#[crate::precondition x < 5]`
+ pub path: Path,
- /// Any tokens after the path.
- ///
- /// E.g. `( Copy )` in `#[derive(Copy)]`
- /// E.g. `x < 5` in `#[crate::precondition x < 5]`
- pub tts: Vec<TokenTree>,
+ /// Any tokens after the path.
+ ///
+ /// E.g. `( Copy )` in `#[derive(Copy)]`
+ /// E.g. `x < 5` in `#[crate::precondition x < 5]`
+ pub tts: Vec<TokenTree>,
- pub is_sugared_doc: bool,
+ pub is_sugared_doc: bool,
+ }
}
impl Attribute {
@@ -49,7 +50,11 @@
if tts.len() >= 3 {
if let TokenTree::Token(Token::Eq) = tts[1] {
if let TokenTree::Token(Token::Literal(ref lit)) = tts[2] {
- return Some((NestedMetaItem::MetaItem(MetaItem::NameValue(ident.clone(), lit.clone())), &tts[3..]));
+ let pair = MetaNameValue {
+ ident: ident.clone(),
+ lit: lit.clone(),
+ };
+ return Some((NestedMetaItem::MetaItem(MetaItem::NameValue(pair)), &tts[3..]));
}
}
}
@@ -58,7 +63,11 @@
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) => {
- Some((NestedMetaItem::MetaItem(MetaItem::List(ident.clone(), nested_meta_items)), &tts[2..]))
+ let list = MetaItemList {
+ ident: ident.clone(),
+ nested: nested_meta_items,
+ };
+ Some((NestedMetaItem::MetaItem(MetaItem::List(list)), &tts[2..]))
}
None => None
@@ -97,7 +106,10 @@
}
if let Some(nested_meta_items) = list_of_nested_meta_items_from_tokens(vec![], tts) {
- return Some(MetaItem::List(name.clone(), nested_meta_items));
+ return Some(MetaItem::List(MetaItemList {
+ ident: name.clone(),
+ nested: nested_meta_items,
+ }));
}
}
}
@@ -105,7 +117,10 @@
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] {
- return Some(MetaItem::NameValue(name.clone(), lit.clone()));
+ return Some(MetaItem::NameValue(MetaNameValue {
+ ident: name.clone(),
+ lit: lit.clone(),
+ }));
}
}
}
@@ -114,37 +129,60 @@
}
}
-/// 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.
-#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
-pub enum AttrStyle {
- /// Attribute of the form `#![...]`.
- Outer,
+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.
+ #[derive(Copy)]
+ pub enum AttrStyle {
+ /// Attribute of the form `#![...]`.
+ Outer,
- /// Attribute of the form `#[...]`.
- Inner,
+ /// Attribute of the form `#[...]`.
+ Inner,
+ }
}
-/// A compile-time attribute item.
-///
-/// E.g. `#[test]`, `#[derive(..)]` or `#[feature = "foo"]`
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-pub enum MetaItem {
- /// Word meta item.
+ast_enum_of_structs! {
+ /// A compile-time attribute item.
///
- /// E.g. `test` as in `#[test]`
- Word(Ident),
+ /// E.g. `#[test]`, `#[derive(..)]` or `#[feature = "foo"]`
+ pub enum MetaItem {
+ /// Word meta item.
+ ///
+ /// E.g. `test` as in `#[test]`
+ pub Word(Ident),
- /// List meta item.
- ///
- /// E.g. `derive(..)` as in `#[derive(..)]`
- List(Ident, Vec<NestedMetaItem>),
+ /// List meta item.
+ ///
+ /// E.g. `derive(..)` as in `#[derive(..)]`
+ pub List(MetaItemList {
+ /// Name of this attribute.
+ ///
+ /// E.g. `derive` in `#[derive(..)]`
+ pub ident: Ident,
- /// Name-value meta item.
- ///
- /// E.g. `feature = "foo"` as in `#[feature = "foo"]`
- NameValue(Ident, Lit),
+ /// Arguments to this attribute
+ ///
+ /// E.g. `..` in `#[derive(..)]`
+ pub nested: Vec<NestedMetaItem>,
+ }),
+
+ /// Name-value meta item.
+ ///
+ /// E.g. `feature = "foo"` as in `#[feature = "foo"]`
+ pub NameValue(MetaNameValue {
+ /// Name of this attribute.
+ ///
+ /// E.g. `feature` in `#[feature = "foo"]`
+ pub ident: Ident,
+
+ /// Arguments to this attribute
+ ///
+ /// E.g. `"foo"` in `#[feature = "foo"]`
+ pub lit: Lit,
+ }),
+ }
}
impl MetaItem {
@@ -154,27 +192,28 @@
/// `feature` as in `#[feature = "foo"]`.
pub fn name(&self) -> &str {
match *self {
- MetaItem::Word(ref name) |
- MetaItem::List(ref name, _) |
- MetaItem::NameValue(ref name, _) => name.as_ref(),
+ MetaItem::Word(ref name) => name.as_ref(),
+ MetaItem::NameValue(ref pair) => pair.ident.as_ref(),
+ MetaItem::List(ref list) => list.ident.as_ref(),
}
}
}
-/// Possible values inside of compile-time attribute lists.
-///
-/// E.g. the '..' in `#[name(..)]`.
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-pub enum NestedMetaItem {
- /// A full `MetaItem`.
+ast_enum_of_structs! {
+ /// Possible values inside of compile-time attribute lists.
///
- /// E.g. `Copy` in `#[derive(Copy)]` would be a `MetaItem::Word(Ident::from("Copy"))`.
- MetaItem(MetaItem),
+ /// E.g. the '..' in `#[name(..)]`.
+ pub enum NestedMetaItem {
+ /// A full `MetaItem`.
+ ///
+ /// E.g. `Copy` in `#[derive(Copy)]` would be a `MetaItem::Word(Ident::from("Copy"))`.
+ pub MetaItem(MetaItem),
- /// A Rust literal.
- ///
- /// E.g. `"name"` in `#[rename("name")]`.
- Literal(Lit),
+ /// A Rust literal.
+ ///
+ /// E.g. `"name"` in `#[rename("name")]`.
+ pub Literal(Lit),
+ }
}
pub trait FilterAttrs<'a> {
@@ -378,37 +417,20 @@
}
}
- impl ToTokens for MetaItem {
+ impl ToTokens for MetaItemList {
fn to_tokens(&self, tokens: &mut Tokens) {
- match *self {
- MetaItem::Word(ref ident) => {
- ident.to_tokens(tokens);
- }
- MetaItem::List(ref ident, ref inner) => {
- ident.to_tokens(tokens);
- tokens.append("(");
- tokens.append_separated(inner, ",");
- tokens.append(")");
- }
- MetaItem::NameValue(ref name, ref value) => {
- name.to_tokens(tokens);
- tokens.append("=");
- value.to_tokens(tokens);
- }
- }
+ self.ident.to_tokens(tokens);
+ tokens.append("(");
+ tokens.append_separated(&self.nested, ",");
+ tokens.append(")");
}
}
- impl ToTokens for NestedMetaItem {
+ impl ToTokens for MetaNameValue {
fn to_tokens(&self, tokens: &mut Tokens) {
- match *self {
- NestedMetaItem::MetaItem(ref nested) => {
- nested.to_tokens(tokens);
- }
- NestedMetaItem::Literal(ref lit) => {
- lit.to_tokens(tokens);
- }
- }
+ self.ident.to_tokens(tokens);
+ tokens.append("=");
+ self.lit.to_tokens(tokens);
}
}
}
diff --git a/src/constant.rs b/src/constant.rs
index ad0d325..2267b50 100644
--- a/src/constant.rs
+++ b/src/constant.rs
@@ -1,38 +1,72 @@
use super::*;
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-pub enum ConstExpr {
- /// A function call
- ///
- /// The first field resolves to the function itself,
- /// and the second field is the list of arguments
- Call(Box<ConstExpr>, Vec<ConstExpr>),
+ast_enum_of_structs! {
+ pub enum ConstExpr {
+ /// A function call
+ pub Call(ConstCall {
+ /// The function being called
+ pub func: Box<ConstExpr>,
- /// A binary operation (For example: `a + b`, `a * b`)
- Binary(BinOp, Box<ConstExpr>, Box<ConstExpr>),
+ /// The arguments to the function being called
+ pub args: Vec<ConstExpr>,
+ }),
- /// A unary operation (For example: `!x`, `*x`)
- Unary(UnOp, Box<ConstExpr>),
+ /// A binary operation (For example: `a + b`, `a * b`)
+ pub Binary(ConstBinary {
+ /// The binary operation this represents
+ pub op: BinOp,
- /// A literal (For example: `1`, `"foo"`)
- Lit(Lit),
+ /// The left-hand-side of the constant binary op
+ pub left: Box<ConstExpr>,
- /// A cast (`foo as f64`)
- Cast(Box<ConstExpr>, Box<Ty>),
+ /// The right-hand-side of the constant binary op
+ pub right: Box<ConstExpr>,
+ }),
- /// Variable reference, possibly containing `::` and/or type
- /// parameters, e.g. foo::bar::<baz>.
- Path(Path),
+ /// A unary operation (For example: `!x`, `*x`)
+ pub Unary(ConstUnary {
+ /// Operation being performed
+ pub op: UnOp,
- /// An indexing operation (`foo[2]`)
- Index(Box<ConstExpr>, Box<ConstExpr>),
+ /// Expression acted on
+ pub expr: Box<ConstExpr>,
+ }),
- /// No-op: used solely so we can pretty-print faithfully
- Paren(Box<ConstExpr>),
+ /// A literal (For example: `1`, `"foo"`)
+ pub Lit(Lit),
- /// If compiling with full support for expression syntax, any expression is
- /// allowed
- Other(Other),
+ /// A cast (`foo as f64`)
+ pub Cast(ConstCast {
+ /// Value being casted
+ pub expr: Box<ConstExpr>,
+
+ /// Type casted to
+ pub ty: Box<Ty>,
+ }),
+
+ /// Variable reference, possibly containing `::` and/or type
+ /// parameters, e.g. foo::bar::<baz>.
+ pub Path(Path),
+
+ /// An indexing operation (`foo[2]`)
+ pub Index(ConstIndex {
+ /// Value that is being indexed
+ pub expr: Box<ConstExpr>,
+
+ /// Index expression
+ pub index: Box<ConstExpr>,
+ }),
+
+ /// No-op: used solely so we can pretty-print faithfully
+ pub Paren(ConstParen {
+ /// Expression that's parenthesized
+ pub expr: Box<ConstExpr>,
+ }),
+
+ /// If compiling with full support for expression syntax, any expression is
+ /// allowed
+ pub Other(Other),
+ }
}
#[cfg(not(feature = "full"))]
@@ -69,20 +103,20 @@
) >>
many0!(alt!(
tap!(args: and_call => {
- e = ConstExpr::Call(Box::new(e), args);
+ e = ConstCall { func: Box::new(e), args: args }.into();
})
|
tap!(more: and_binary => {
let (op, other) = more;
- e = ConstExpr::Binary(op, Box::new(e), Box::new(other));
+ e = ConstBinary { op: op, left: Box::new(e), right: Box::new(other) }.into();
})
|
tap!(ty: and_cast => {
- e = ConstExpr::Cast(Box::new(e), Box::new(ty));
+ e = ConstCast { expr: Box::new(e), ty: Box::new(ty) }.into();
})
|
tap!(i: and_index => {
- e = ConstExpr::Index(Box::new(e), Box::new(i));
+ e = ConstIndex { expr: Box::new(e), index: Box::new(i) }.into();
})
)) >>
(e)
@@ -100,7 +134,7 @@
named!(expr_unary -> ConstExpr, do_parse!(
operator: unop >>
operand: const_expr >>
- (ConstExpr::Unary(operator, Box::new(operand)))
+ (ConstUnary { op: operator, expr: Box::new(operand) }.into())
));
named!(expr_lit -> ConstExpr, map!(lit, ConstExpr::Lit));
@@ -113,7 +147,7 @@
punct!("(") >>
e: const_expr >>
punct!(")") >>
- (ConstExpr::Paren(Box::new(e)))
+ (ConstParen { expr: Box::new(e) }.into())
));
named!(and_cast -> Ty, do_parse!(
@@ -128,46 +162,52 @@
use super::*;
use quote::{Tokens, ToTokens};
- impl ToTokens for ConstExpr {
+ impl ToTokens for ConstCall {
fn to_tokens(&self, tokens: &mut Tokens) {
- match *self {
- ConstExpr::Call(ref func, ref args) => {
- func.to_tokens(tokens);
- tokens.append("(");
- tokens.append_separated(args, ",");
- tokens.append(")");
- }
- ConstExpr::Binary(op, ref left, ref right) => {
- left.to_tokens(tokens);
- op.to_tokens(tokens);
- right.to_tokens(tokens);
- }
- ConstExpr::Unary(op, ref expr) => {
- op.to_tokens(tokens);
- expr.to_tokens(tokens);
- }
- ConstExpr::Lit(ref lit) => lit.to_tokens(tokens),
- ConstExpr::Cast(ref expr, ref ty) => {
- expr.to_tokens(tokens);
- tokens.append("as");
- ty.to_tokens(tokens);
- }
- ConstExpr::Path(ref path) => path.to_tokens(tokens),
- ConstExpr::Index(ref expr, ref index) => {
- expr.to_tokens(tokens);
- tokens.append("[");
- index.to_tokens(tokens);
- tokens.append("]");
- }
- ConstExpr::Paren(ref expr) => {
- tokens.append("(");
- expr.to_tokens(tokens);
- tokens.append(")");
- }
- ConstExpr::Other(ref other) => {
- other.to_tokens(tokens);
- }
- }
+ self.func.to_tokens(tokens);
+ tokens.append("(");
+ tokens.append_separated(&self.args, ",");
+ tokens.append(")");
+ }
+ }
+
+ impl ToTokens for ConstBinary {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ self.left.to_tokens(tokens);
+ self.op.to_tokens(tokens);
+ self.right.to_tokens(tokens);
+ }
+ }
+
+ impl ToTokens for ConstUnary {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ self.op.to_tokens(tokens);
+ self.expr.to_tokens(tokens);
+ }
+ }
+
+ impl ToTokens for ConstCast {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ self.expr.to_tokens(tokens);
+ tokens.append("as");
+ self.ty.to_tokens(tokens);
+ }
+ }
+
+ 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("]");
+ }
+ }
+
+ impl ToTokens for ConstParen {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ tokens.append("(");
+ self.expr.to_tokens(tokens);
+ tokens.append(")");
}
}
diff --git a/src/data.rs b/src/data.rs
index 69df303..d01d9e5 100644
--- a/src/data.rs
+++ b/src/data.rs
@@ -1,32 +1,34 @@
use super::*;
-/// An enum variant.
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-pub struct Variant {
- /// Name of the variant.
- pub ident: Ident,
+ast_struct! {
+ /// An enum variant.
+ pub struct Variant {
+ /// Name of the variant.
+ pub ident: Ident,
- /// Attributes tagged on the variant.
- pub attrs: Vec<Attribute>,
+ /// Attributes tagged on the variant.
+ pub attrs: Vec<Attribute>,
- /// Type of variant.
- pub data: VariantData,
+ /// Type of variant.
+ pub data: VariantData,
- /// Explicit discriminant, e.g. `Foo = 1`
- pub discriminant: Option<ConstExpr>,
+ /// Explicit discriminant, e.g. `Foo = 1`
+ pub discriminant: Option<ConstExpr>,
+ }
}
-/// Data stored within an enum variant or struct.
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-pub enum VariantData {
- /// Struct variant, e.g. `Point { x: f64, y: f64 }`.
- Struct(Vec<Field>),
+ast_enum! {
+ /// Data stored within an enum variant or struct.
+ pub enum VariantData {
+ /// Struct variant, e.g. `Point { x: f64, y: f64 }`.
+ Struct(Vec<Field>),
- /// Tuple variant, e.g. `Some(T)`.
- Tuple(Vec<Field>),
+ /// Tuple variant, e.g. `Some(T)`.
+ Tuple(Vec<Field>),
- /// Unit variant, e.g. `None`.
- Unit,
+ /// Unit variant, e.g. `None`.
+ Unit,
+ }
}
impl VariantData {
@@ -49,39 +51,40 @@
}
}
-/// A field of a struct or enum variant.
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-pub struct Field {
- /// Name of the field, if any.
- ///
- /// Fields of tuple structs have no names.
- pub ident: Option<Ident>,
+ast_struct! {
+ /// A field of a struct or enum variant.
+ pub struct Field {
+ /// Name of the field, if any.
+ ///
+ /// Fields of tuple structs have no names.
+ pub ident: Option<Ident>,
- /// Visibility of the field.
- pub vis: Visibility,
+ /// Visibility of the field.
+ pub vis: Visibility,
- /// Attributes tagged on the field.
- pub attrs: Vec<Attribute>,
+ /// Attributes tagged on the field.
+ pub attrs: Vec<Attribute>,
- /// Type of the field.
- pub ty: Ty,
+ /// Type of the field.
+ pub ty: Ty,
+ }
}
+ast_enum! {
+ /// Visibility level of an item.
+ pub enum Visibility {
+ /// Public, i.e. `pub`.
+ Public,
-/// Visibility level of an item.
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-pub enum Visibility {
- /// Public, i.e. `pub`.
- Public,
+ /// Crate-visible, i.e. `pub(crate)`.
+ Crate,
- /// Crate-visible, i.e. `pub(crate)`.
- Crate,
+ /// Restricted, e.g. `pub(self)` or `pub(super)` or `pub(in some::module)`.
+ Restricted(Box<Path>),
- /// Restricted, e.g. `pub(self)` or `pub(super)` or `pub(in some::module)`.
- Restricted(Box<Path>),
-
- /// Inherited, i.e. private.
- Inherited,
+ /// Inherited, i.e. private.
+ Inherited,
+ }
}
#[cfg(feature = "parsing")]
diff --git a/src/derive.rs b/src/derive.rs
index 306c352..3b22b0f 100644
--- a/src/derive.rs
+++ b/src/derive.rs
@@ -1,32 +1,35 @@
use super::*;
-/// Struct or enum sent to a `proc_macro_derive` macro.
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-pub struct DeriveInput {
- /// Name of the struct or enum.
- pub ident: Ident,
+ast_struct! {
+ /// Struct or enum sent to a `proc_macro_derive` macro.
+ pub struct DeriveInput {
+ /// Name of the struct or enum.
+ pub ident: Ident,
- /// Visibility of the struct or enum.
- pub vis: Visibility,
+ /// Visibility of the struct or enum.
+ pub vis: Visibility,
- /// Attributes tagged on the whole struct or enum.
- pub attrs: Vec<Attribute>,
+ /// Attributes tagged on the whole struct or enum.
+ pub attrs: Vec<Attribute>,
- /// Generics required to complete the definition.
- pub generics: Generics,
+ /// Generics required to complete the definition.
+ pub generics: Generics,
- /// Data within the struct or enum.
- pub body: Body,
+ /// Data within the struct or enum.
+ pub body: Body,
+ }
}
-/// Body of a derived struct or enum.
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-pub enum Body {
- /// It's an enum.
- Enum(Vec<Variant>),
- /// It's a struct.
- Struct(VariantData),
+ast_enum! {
+ /// Body of a derived struct or enum.
+ pub enum Body {
+ /// It's an enum.
+ Enum(Vec<Variant>),
+
+ /// It's a struct.
+ Struct(VariantData),
+ }
}
#[cfg(feature = "parsing")]
diff --git a/src/expr.rs b/src/expr.rs
index fae3e65..39ab6c7 100644
--- a/src/expr.rs
+++ b/src/expr.rs
@@ -1,13 +1,14 @@
use super::*;
-/// An expression.
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-pub struct Expr {
- /// Type of the expression.
- pub node: ExprKind,
+ast_struct! {
+ /// An expression.
+ pub struct Expr {
+ /// Type of the expression.
+ pub node: ExprKind,
- /// Attributes tagged on the expression.
- pub attrs: Vec<Attribute>,
+ /// Attributes tagged on the expression.
+ pub attrs: Vec<Attribute>,
+ }
}
impl From<ExprKind> for Expr {
@@ -19,350 +20,472 @@
}
}
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-pub enum ExprKind {
- /// A `box x` expression.
- Box(Box<Expr>),
+ast_enum_of_structs! {
+ pub enum ExprKind {
+ /// A `box x` expression.
+ pub Box(ExprBox {
+ pub expr: Box<Expr>,
+ }),
- /// First expr is the place; second expr is the value.
- ///
- /// E.g. 'plae <- val'.
- InPlace(Box<Expr>, Box<Expr>),
+ /// E.g. 'place <- val'.
+ pub InPlace(ExprInPlace {
+ pub place: Box<Expr>,
+ pub value: Box<Expr>,
+ }),
- /// An array, e.g. `[a, b, c, d]`.
- Array(Vec<Expr>),
+ /// An array, e.g. `[a, b, c, d]`.
+ pub Array(ExprArray {
+ pub exprs: Vec<Expr>,
+ }),
- /// A function call.
- ///
- /// The first field resolves to the function itself,
- /// and the second field is the list of arguments
- Call(Box<Expr>, Vec<Expr>),
+ /// A function call.
+ pub Call(ExprCall {
+ pub func: Box<Expr>,
+ pub args: Vec<Expr>,
+ }),
- /// A method call (`x.foo::<Bar, Baz>(a, b, c, d)`)
- ///
- /// The `Ident` is the identifier for the method name.
- /// 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])`.
- MethodCall(Ident, Vec<Ty>, Vec<Expr>),
+ /// A method call (`x.foo::<Bar, Baz>(a, b, c, d)`)
+ ///
+ /// The `Ident` is the identifier for the method name.
+ /// 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 method: Ident,
+ pub typarams: Vec<Ty>,
+ pub args: Vec<Expr>,
+ }),
- /// A tuple, e.g. `(a, b, c, d)`.
- Tup(Vec<Expr>),
+ /// A tuple, e.g. `(a, b, c, d)`.
+ pub Tup(ExprTup {
+ pub args: Vec<Expr>,
+ }),
- /// A binary operation, e.g. `a + b`, `a * b`.
- Binary(BinOp, Box<Expr>, Box<Expr>),
+ /// A binary operation, e.g. `a + b`, `a * b`.
+ pub Binary(ExprBinary {
+ pub op: BinOp,
+ pub left: Box<Expr>,
+ pub right: Box<Expr>,
+ }),
- /// A unary operation, e.g. `!x`, `*x`.
- Unary(UnOp, Box<Expr>),
+ /// A unary operation, e.g. `!x`, `*x`.
+ pub Unary(ExprUnary {
+ pub op: UnOp,
+ pub expr: Box<Expr>,
+ }),
- /// A literal, e.g. `1`, `"foo"`.
- Lit(Lit),
+ /// A literal, e.g. `1`, `"foo"`.
+ pub Lit(Lit),
- /// A cast, e.g. `foo as f64`.
- Cast(Box<Expr>, Box<Ty>),
+ /// A cast, e.g. `foo as f64`.
+ pub Cast(ExprCast {
+ pub expr: Box<Expr>,
+ pub ty: Box<Ty>,
+ }),
- /// A type ascription, e.g. `foo: f64`.
- Type(Box<Expr>, Box<Ty>),
+ /// A type ascription, e.g. `foo: f64`.
+ pub Type(ExprType {
+ pub expr: Box<Expr>,
+ pub ty: Box<Ty>,
+ }),
- /// An `if` block, with an optional else block
- ///
- /// E.g., `if expr { block } else { expr }`
- If(Box<Expr>, Block, Option<Box<Expr>>),
+ /// An `if` block, with an optional else block
+ ///
+ /// E.g., `if expr { block } else { expr }`
+ pub If(ExprIf {
+ pub cond: Box<Expr>,
+ pub if_true: Block,
+ pub if_false: Option<Box<Expr>>,
+ }),
- /// An `if let` expression with an optional else block
- ///
- /// E.g., `if let pat = expr { block } else { expr }`
- ///
- /// This is desugared to a `match` expression.
- IfLet(Box<Pat>, Box<Expr>, Block, Option<Box<Expr>>),
+ /// An `if let` expression with an optional else block
+ ///
+ /// E.g., `if let pat = expr { block } else { expr }`
+ ///
+ /// This is desugared to a `match` expression.
+ pub IfLet(ExprIfLet {
+ pub pat: Box<Pat>,
+ pub expr: Box<Expr>,
+ pub if_true: Block,
+ pub if_false: Option<Box<Expr>>,
+ }),
- /// A while loop, with an optional label
- ///
- /// E.g., `'label: while expr { block }`
- While(Box<Expr>, Block, Option<Ident>),
+ /// A while loop, with an optional label
+ ///
+ /// E.g., `'label: while expr { block }`
+ pub While(ExprWhile {
+ pub cond: Box<Expr>,
+ pub body: Block,
+ pub label: Option<Ident>,
+ }),
- /// A while-let loop, with an optional label.
- ///
- /// E.g., `'label: while let pat = expr { block }`
- ///
- /// This is desugared to a combination of `loop` and `match` expressions.
- WhileLet(Box<Pat>, Box<Expr>, Block, Option<Ident>),
+ /// A while-let loop, with an optional label.
+ ///
+ /// E.g., `'label: while let pat = expr { block }`
+ ///
+ /// This is desugared to a combination of `loop` and `match` expressions.
+ pub WhileLet(ExprWhileLet {
+ pub pat: Box<Pat>,
+ pub expr: Box<Expr>,
+ pub body: Block,
+ pub label: Option<Ident>,
+ }),
- /// A for loop, with an optional label.
- ///
- /// E.g., `'label: for pat in expr { block }`
- ///
- /// This is desugared to a combination of `loop` and `match` expressions.
- ForLoop(Box<Pat>, Box<Expr>, Block, Option<Ident>),
+ /// A for loop, with an optional label.
+ ///
+ /// E.g., `'label: for pat in expr { block }`
+ ///
+ /// This is desugared to a combination of `loop` and `match` expressions.
+ pub ForLoop(ExprForLoop {
+ pub pat: Box<Pat>,
+ pub expr: Box<Expr>,
+ pub body: Block,
+ pub label: Option<Ident>,
+ }),
- /// Conditionless loop with an optional label.
- ///
- /// E.g. `'label: loop { block }`
- Loop(Block, Option<Ident>),
+ /// Conditionless loop with an optional label.
+ ///
+ /// E.g. `'label: loop { block }`
+ pub Loop(ExprLoop {
+ pub body: Block,
+ pub label: Option<Ident>,
+ }),
- /// A `match` block.
- Match(Box<Expr>, Vec<Arm>),
+ /// A `match` block.
+ pub Match(ExprMatch {
+ pub expr: Box<Expr>,
+ pub arms: Vec<Arm>,
+ }),
- /// A closure (for example, `move |a, b, c| a + b + c`)
- Closure(CaptureBy, Box<FnDecl>, Box<Expr>),
+ /// A closure (for example, `move |a, b, c| a + b + c`)
+ pub Closure(ExprClosure {
+ pub capture: CaptureBy,
+ pub decl: Box<FnDecl>,
+ pub body: Box<Expr>,
+ }),
- /// A block (`{ ... }` or `unsafe { ... }`)
- Block(Unsafety, Block),
+ /// A block (`{ ... }` or `unsafe { ... }`)
+ pub Block(ExprBlock {
+ pub unsafety: Unsafety,
+ pub block: Block,
+ }),
- /// An assignment (`a = foo()`)
- Assign(Box<Expr>, Box<Expr>),
+ /// An assignment (`a = foo()`)
+ pub Assign(ExprAssign {
+ pub left: Box<Expr>,
+ pub right: Box<Expr>,
+ }),
- /// An assignment with an operator
- ///
- /// For example, `a += 1`.
- AssignOp(BinOp, Box<Expr>, Box<Expr>),
+ /// An assignment with an operator
+ ///
+ /// For example, `a += 1`.
+ pub AssignOp(ExprAssignOp {
+ pub op: BinOp,
+ pub left: Box<Expr>,
+ pub right: Box<Expr>,
+ }),
- /// Access of a named struct field (`obj.foo`)
- Field(Box<Expr>, Ident),
+ /// Access of a named struct field (`obj.foo`)
+ pub Field(ExprField {
+ pub expr: Box<Expr>,
+ pub field: Ident,
+ }),
- /// Access of an unnamed field of a struct or tuple-struct
- ///
- /// For example, `foo.0`.
- TupField(Box<Expr>, usize),
+ /// Access of an unnamed field of a struct or tuple-struct
+ ///
+ /// For example, `foo.0`.
+ pub TupField(ExprTupField {
+ pub expr: Box<Expr>,
+ pub field: usize,
+ }),
- /// An indexing operation (`foo[2]`)
- Index(Box<Expr>, Box<Expr>),
+ /// An indexing operation (`foo[2]`)
+ pub Index(ExprIndex {
+ pub expr: Box<Expr>,
+ pub index: Box<Expr>,
+ }),
- /// A range (`1..2`, `1..`, `..2`, `1...2`, `1...`, `...2`)
- Range(Option<Box<Expr>>, Option<Box<Expr>>, RangeLimits),
+ /// A range (`1..2`, `1..`, `..2`, `1...2`, `1...`, `...2`)
+ pub Range(ExprRange {
+ pub from: Option<Box<Expr>>,
+ pub to: Option<Box<Expr>>,
+ pub limits: RangeLimits,
+ }),
- /// Variable reference, possibly containing `::` and/or type
- /// parameters, e.g. foo::bar::<baz>.
- ///
- /// Optionally "qualified",
- /// E.g. `<Vec<T> as SomeTrait>::SomeType`.
- Path(Option<QSelf>, Path),
+ /// Variable reference, possibly containing `::` and/or type
+ /// parameters, e.g. foo::bar::<baz>.
+ ///
+ /// Optionally "qualified",
+ /// E.g. `<Vec<T> as SomeTrait>::SomeType`.
+ pub Path(ExprPath {
+ pub qself: Option<QSelf>,
+ pub path: Path,
+ }),
- /// A referencing operation (`&a` or `&mut a`)
- AddrOf(Mutability, Box<Expr>),
+ /// A referencing operation (`&a` or `&mut a`)
+ pub AddrOf(ExprAddrOf {
+ pub mutbl: Mutability,
+ pub expr: Box<Expr>,
+ }),
- /// A `break`, with an optional label to break, and an optional expression
- Break(Option<Ident>, Option<Box<Expr>>),
+ /// A `break`, with an optional label to break, and an optional expression
+ pub Break(ExprBreak {
+ pub label: Option<Ident>,
+ pub expr: Option<Box<Expr>>,
+ }),
- /// A `continue`, with an optional label
- Continue(Option<Ident>),
+ /// A `continue`, with an optional label
+ pub Continue(ExprContinue {
+ pub label: Option<Ident>,
+ }),
- /// A `return`, with an optional value to be returned
- Ret(Option<Box<Expr>>),
+ /// A `return`, with an optional value to be returned
+ pub Ret(ExprRet {
+ pub expr: Option<Box<Expr>>,
+ }),
- /// A macro invocation; pre-expansion
- Mac(Mac),
+ /// A macro invocation; pre-expansion
+ pub Mac(Mac),
- /// A struct literal expression.
- ///
- /// For example, `Foo {x: 1, y: 2}`, or
- /// `Foo {x: 1, .. base}`, where `base` is the `Option<Expr>`.
- Struct(Path, Vec<FieldValue>, Option<Box<Expr>>),
+ /// A struct literal expression.
+ ///
+ /// For example, `Foo {x: 1, y: 2}`, or
+ /// `Foo {x: 1, .. base}`, where `base` is the `Option<Expr>`.
+ pub Struct(ExprStruct {
+ pub path: Path,
+ pub fields: Vec<FieldValue>,
+ pub rest: Option<Box<Expr>>,
+ }),
- /// An array literal constructed from one repeated element.
- ///
- /// For example, `[1; 5]`. The first expression is the element
- /// to be repeated; the second is the number of times to repeat it.
- Repeat(Box<Expr>, Box<Expr>),
+ /// An array literal constructed from one repeated element.
+ ///
+ /// 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 expr: Box<Expr>,
+ pub amt: Box<Expr>,
+ }),
- /// No-op: used solely so we can pretty-print faithfully
- Paren(Box<Expr>),
+ /// No-op: used solely so we can pretty-print faithfully
+ pub Paren(ExprParen {
+ pub expr: Box<Expr>,
+ }),
- /// `expr?`
- Try(Box<Expr>),
+ /// `expr?`
+ pub Try(ExprTry {
+ pub expr: Box<Expr>,
+ }),
- /// A catch expression.
- ///
- /// E.g. `do catch { block }`
- Catch(Block),
+ /// A catch expression.
+ ///
+ /// E.g. `do catch { block }`
+ pub Catch(ExprCatch {
+ pub block: Block,
+ }),
+ }
}
-/// A field-value pair in a struct literal.
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-pub struct FieldValue {
- /// Name of the field.
- pub ident: Ident,
+ast_struct! {
+ /// A field-value pair in a struct literal.
+ pub struct FieldValue {
+ /// Name of the field.
+ pub ident: Ident,
- /// Value of the field.
- pub expr: Expr,
+ /// Value of the field.
+ pub expr: Expr,
- /// Whether this is a shorthand field, e.g. `Struct { x }`
- /// instead of `Struct { x: x }`.
- pub is_shorthand: bool,
+ /// Whether this is a shorthand field, e.g. `Struct { x }`
+ /// instead of `Struct { x: x }`.
+ pub is_shorthand: bool,
- /// Attributes tagged on the field.
- pub attrs: Vec<Attribute>,
+ /// Attributes tagged on the field.
+ pub attrs: Vec<Attribute>,
+ }
}
-/// A Block (`{ .. }`).
-///
-/// E.g. `{ .. }` as in `fn foo() { .. }`
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-pub struct Block {
- /// Statements in a block
- pub stmts: Vec<Stmt>,
+ast_struct! {
+ /// A Block (`{ .. }`).
+ ///
+ /// E.g. `{ .. }` as in `fn foo() { .. }`
+ pub struct Block {
+ /// Statements in a block
+ pub stmts: Vec<Stmt>,
+ }
}
-/// A statement, usually ending in a semicolon.
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-pub enum Stmt {
- /// A local (let) binding.
- Local(Box<Local>),
+ast_enum! {
+ /// A statement, usually ending in a semicolon.
+ pub enum Stmt {
+ /// A local (let) binding.
+ Local(Box<Local>),
- /// An item definition.
- Item(Box<Item>),
+ /// An item definition.
+ Item(Box<Item>),
- /// Expr without trailing semicolon.
- Expr(Box<Expr>),
+ /// Expr without trailing semicolon.
+ Expr(Box<Expr>),
- /// Expression with trailing semicolon;
- Semi(Box<Expr>),
+ /// Expression with trailing semicolon;
+ Semi(Box<Expr>),
- /// Macro invocation.
- Mac(Box<(Mac, MacStmtStyle, Vec<Attribute>)>),
+ /// Macro invocation.
+ Mac(Box<(Mac, MacStmtStyle, Vec<Attribute>)>),
+ }
}
-/// How a macro was invoked.
-#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
-pub enum MacStmtStyle {
- /// The macro statement had a trailing semicolon, e.g. `foo! { ... };`
- /// `foo!(...);`, `foo![...];`
- Semicolon,
+ast_enum! {
+ /// How a macro was invoked.
+ #[derive(Copy)]
+ pub enum MacStmtStyle {
+ /// The macro statement had a trailing semicolon, e.g. `foo! { ... };`
+ /// `foo!(...);`, `foo![...];`
+ Semicolon,
- /// The macro statement had braces; e.g. foo! { ... }
- Braces,
+ /// The macro statement had braces; e.g. foo! { ... }
+ Braces,
- /// The macro statement had parentheses or brackets and no semicolon; e.g.
- /// `foo!(...)`. All of these will end up being converted into macro
- /// expressions.
- NoBraces,
+ /// The macro statement had parentheses or brackets and no semicolon; e.g.
+ /// `foo!(...)`. All of these will end up being converted into macro
+ /// expressions.
+ NoBraces,
+ }
}
-/// Local represents a `let` statement, e.g., `let <pat>:<ty> = <expr>;`
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-pub struct Local {
- pub pat: Box<Pat>,
- pub ty: Option<Box<Ty>>,
+ast_struct! {
+ /// Local represents a `let` statement, e.g., `let <pat>:<ty> = <expr>;`
+ pub struct Local {
+ pub pat: Box<Pat>,
+ pub ty: Option<Box<Ty>>,
- /// Initializer expression to set the value, if any
- pub init: Option<Box<Expr>>,
- pub attrs: Vec<Attribute>,
+ /// Initializer expression to set the value, if any
+ pub init: Option<Box<Expr>>,
+ pub attrs: Vec<Attribute>,
+ }
}
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-// 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,
+ast_enum! {
+ // 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,
- /// 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>>),
+ /// 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>>),
- /// 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),
+ /// 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),
- /// 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>),
+ /// 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>),
- /// 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),
+ /// 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),
- /// 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>),
- /// A `box` pattern
- Box(Box<Pat>),
- /// A reference pattern, e.g. `&mut (a, b)`
- Ref(Box<Pat>, Mutability),
- /// A literal
- Lit(Box<Expr>),
- /// A range pattern, e.g. `1...2`
- Range(Box<Expr>, Box<Expr>, 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>),
- /// A macro pattern; pre-expansion
- Mac(Mac),
+ /// 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>),
+ /// A `box` pattern
+ Box(Box<Pat>),
+ /// A reference pattern, e.g. `&mut (a, b)`
+ Ref(Box<Pat>, Mutability),
+ /// A literal
+ Lit(Box<Expr>),
+ /// A range pattern, e.g. `1...2`
+ Range(Box<Expr>, Box<Expr>, 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>),
+ /// A macro pattern; pre-expansion
+ Mac(Mac),
+ }
}
-/// An arm of a 'match'.
-///
-/// E.g. `0...10 => { println!("match!") }` as in
-///
-/// ```rust,ignore
-/// match n {
-/// 0...10 => { println!("match!") },
-/// // ..
-/// }
-/// ```
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-pub struct Arm {
- pub attrs: Vec<Attribute>,
- pub pats: Vec<Pat>,
- pub guard: Option<Box<Expr>>,
- pub body: Box<Expr>,
+ast_struct! {
+ /// An arm of a 'match'.
+ ///
+ /// E.g. `0...10 => { println!("match!") }` as in
+ ///
+ /// ```rust,ignore
+ /// match n {
+ /// 0...10 => { println!("match!") },
+ /// // ..
+ /// }
+ /// ```
+ pub struct Arm {
+ pub attrs: Vec<Attribute>,
+ pub pats: Vec<Pat>,
+ pub guard: Option<Box<Expr>>,
+ pub body: Box<Expr>,
+ }
}
-/// A capture clause
-#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
-pub enum CaptureBy {
- Value,
- Ref,
+ast_enum! {
+ /// A capture clause
+ #[derive(Copy)]
+ pub enum CaptureBy {
+ Value,
+ Ref,
+ }
}
-/// Limit types of a range (inclusive or exclusive)
-#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
-pub enum RangeLimits {
- /// Inclusive at the beginning, exclusive at the end
- HalfOpen,
- /// Inclusive at the beginning and end
- Closed,
+ast_enum! {
+ /// Limit types of a range (inclusive or exclusive)
+ #[derive(Copy)]
+ pub enum RangeLimits {
+ /// Inclusive at the beginning, exclusive at the end
+ HalfOpen,
+ /// Inclusive at the beginning and end
+ Closed,
+ }
}
-/// A single field in a struct pattern
-///
-/// Patterns like the fields of Foo `{ x, ref y, ref mut z }`
-/// are treated the same as `x: x, y: ref y, z: ref mut z`,
-/// except `is_shorthand` is true
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-pub struct FieldPat {
- /// The identifier for the field
- pub ident: Ident,
- /// The pattern the field is destructured to
- pub pat: Box<Pat>,
- pub is_shorthand: bool,
- pub attrs: Vec<Attribute>,
+ast_struct! {
+ /// A single field in a struct pattern
+ ///
+ /// Patterns like the fields of Foo `{ x, ref y, ref mut z }`
+ /// are treated the same as `x: x, y: ref y, z: ref mut z`,
+ /// except `is_shorthand` is true
+ pub struct FieldPat {
+ /// The identifier for the field
+ pub ident: Ident,
+ /// The pattern the field is destructured to
+ pub pat: Box<Pat>,
+ pub is_shorthand: bool,
+ pub attrs: Vec<Attribute>,
+ }
}
-#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
-pub enum BindingMode {
- ByRef(Mutability),
- ByValue(Mutability),
+ast_enum! {
+ #[derive(Copy)]
+ pub enum BindingMode {
+ ByRef(Mutability),
+ ByValue(Mutability),
+ }
}
#[cfg(feature = "parsing")]
pub mod parsing {
use super::*;
use {BinOp, Delimited, DelimToken, FnArg, FnDecl, FunctionRetTy, Ident, Lifetime, Mac,
- TokenTree, Ty, UnOp, Unsafety};
+ TokenTree, Ty, UnOp, Unsafety, ArgCaptured, TyInfer};
use attr::parsing::outer_attr;
use generics::parsing::lifetime;
use ident::parsing::{ident, wordlike};
@@ -448,56 +571,93 @@
) >>
many0!(alt!(
tap!(args: and_call => {
- e = ExprKind::Call(Box::new(e.into()), args);
+ e = ExprCall {
+ func: Box::new(e.into()),
+ args: args,
+ }.into();
})
|
tap!(more: and_method_call => {
let (method, ascript, mut args) = more;
args.insert(0, e.into());
- e = ExprKind::MethodCall(method, ascript, args);
+ e = ExprMethodCall {
+ method: method,
+ typarams: ascript,
+ args: args,
+ }.into();
})
|
tap!(more: call!(and_binary, allow_struct) => {
let (op, other) = more;
- e = ExprKind::Binary(op, Box::new(e.into()), Box::new(other));
+ e = ExprBinary {
+ op: op,
+ left: Box::new(e.into()),
+ right: Box::new(other),
+ }.into();
})
|
tap!(ty: and_cast => {
- e = ExprKind::Cast(Box::new(e.into()), Box::new(ty));
+ e = ExprCast {
+ expr: Box::new(e.into()),
+ ty: Box::new(ty),
+ }.into();
})
|
tap!(ty: and_ascription => {
- e = ExprKind::Type(Box::new(e.into()), Box::new(ty));
+ e = ExprType {
+ expr: Box::new(e.into()),
+ ty: Box::new(ty),
+ }.into();
})
|
tap!(v: call!(and_assign, allow_struct) => {
- e = ExprKind::Assign(Box::new(e.into()), Box::new(v));
+ e = ExprAssign {
+ left: Box::new(e.into()),
+ right: Box::new(v),
+ }.into();
})
|
tap!(more: call!(and_assign_op, allow_struct) => {
let (op, v) = more;
- e = ExprKind::AssignOp(op, Box::new(e.into()), Box::new(v));
+ e = ExprAssignOp {
+ op: op,
+ left: Box::new(e.into()),
+ right: Box::new(v),
+ }.into();
})
|
tap!(field: and_field => {
- e = ExprKind::Field(Box::new(e.into()), field);
+ e = ExprField {
+ expr: Box::new(e.into()),
+ field: field,
+ }.into();
})
|
tap!(field: and_tup_field => {
- e = ExprKind::TupField(Box::new(e.into()), field as usize);
+ e = ExprTupField {
+ expr: Box::new(e.into()),
+ field: field as usize,
+ }.into();
})
|
tap!(i: and_index => {
- e = ExprKind::Index(Box::new(e.into()), Box::new(i));
+ e = ExprIndex {
+ expr: Box::new(e.into()),
+ index: Box::new(i),
+ }.into();
})
|
tap!(more: call!(and_range, allow_struct) => {
let (limits, hi) = more;
- e = ExprKind::Range(Some(Box::new(e.into())), hi.map(Box::new), limits);
+ e = ExprRange {
+ from: Some(Box::new(e.into())),
+ to: hi.map(Box::new),
+ limits: limits,
+ }.into();
})
|
tap!(_try: punct!("?") => {
- e = ExprKind::Try(Box::new(e.into()));
+ e = ExprTry { expr: Box::new(e.into()) }.into();
})
)) >>
(e.into())
@@ -510,13 +670,13 @@
punct!("(") >>
e: expr >>
punct!(")") >>
- (ExprKind::Paren(Box::new(e)))
+ (ExprParen { expr: Box::new(e) }.into())
));
named_ambiguous_expr!(expr_box -> ExprKind, allow_struct, do_parse!(
keyword!("box") >>
inner: ambiguous_expr!(allow_struct) >>
- (ExprKind::Box(Box::new(inner)))
+ (ExprBox { expr: Box::new(inner) }.into())
));
named!(expr_in_place -> ExprKind, do_parse!(
@@ -525,19 +685,23 @@
punct!("{") >>
value: within_block >>
punct!("}") >>
- (ExprKind::InPlace(
- Box::new(place),
- Box::new(ExprKind::Block(Unsafety::Normal, Block {
- stmts: value,
- }).into()),
- ))
+ (ExprInPlace {
+ place: Box::new(place),
+ value: Box::new(Expr {
+ node: ExprBlock {
+ unsafety: Unsafety::Normal,
+ block: Block { stmts: value, },
+ }.into(),
+ attrs: Vec::new(),
+ }),
+ }.into())
));
named!(expr_array -> ExprKind, do_parse!(
punct!("[") >>
elems: terminated_list!(punct!(","), expr) >>
punct!("]") >>
- (ExprKind::Array(elems))
+ (ExprArray { exprs: elems }.into())
));
named!(and_call -> Vec<Expr>, do_parse!(
@@ -568,7 +732,7 @@
punct!("(") >>
elems: terminated_list!(punct!(","), expr) >>
punct!(")") >>
- (ExprKind::Tup(elems))
+ (ExprTup { args: elems }.into())
));
named_ambiguous_expr!(and_binary -> (BinOp, Expr), allow_struct, tuple!(
@@ -579,7 +743,7 @@
named_ambiguous_expr!(expr_unary -> ExprKind, allow_struct, do_parse!(
operator: unop >>
operand: ambiguous_expr!(allow_struct) >>
- (ExprKind::Unary(operator, Box::new(operand)))
+ (ExprUnary { op: operator, expr: Box::new(operand) }.into())
));
named!(expr_lit -> ExprKind, map!(lit, ExprKind::Lit));
@@ -624,28 +788,29 @@
punct!("{") >>
else_block: within_block >>
punct!("}") >>
- (ExprKind::Block(Unsafety::Normal, Block {
- stmts: else_block,
+ (ExprKind::Block(ExprBlock {
+ unsafety: Unsafety::Normal,
+ block: Block { stmts: else_block },
}).into())
)
)
)) >>
(match cond {
- Cond::Let(pat, expr) => ExprKind::IfLet(
- Box::new(pat),
- Box::new(expr),
- Block {
+ Cond::Let(pat, expr) => ExprIfLet {
+ pat: Box::new(pat),
+ expr: Box::new(expr),
+ if_true: Block {
stmts: then_block,
},
- else_block.map(|els| Box::new(els.into())),
- ),
- Cond::Expr(cond) => ExprKind::If(
- Box::new(cond),
- Block {
+ 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,
},
- else_block.map(|els| Box::new(els.into())),
- ),
+ if_false: else_block.map(|els| Box::new(els.into())),
+ }.into(),
})
));
@@ -656,14 +821,19 @@
keyword!("in") >>
expr: expr_no_struct >>
loop_block: block >>
- (ExprKind::ForLoop(Box::new(pat), Box::new(expr), loop_block, lbl))
+ (ExprForLoop {
+ pat: Box::new(pat),
+ expr: Box::new(expr),
+ body: loop_block,
+ label: lbl,
+ }.into())
));
named!(expr_loop -> ExprKind, do_parse!(
lbl: option!(terminated!(label, punct!(":"))) >>
keyword!("loop") >>
loop_block: block >>
- (ExprKind::Loop(loop_block, lbl))
+ (ExprLoop { body: loop_block, label: lbl }.into())
));
named!(expr_match -> ExprKind, do_parse!(
@@ -678,21 +848,24 @@
)) >>
last_arm: option!(match_arm) >>
punct!("}") >>
- (ExprKind::Match(Box::new(obj), {
- arms.extend(last_arm);
- arms
- }))
+ (ExprMatch {
+ expr: Box::new(obj),
+ arms: {
+ arms.extend(last_arm);
+ arms
+ },
+ }.into())
));
named!(expr_catch -> ExprKind, do_parse!(
keyword!("do") >>
keyword!("catch") >>
catch_block: block >>
- (ExprKind::Catch(catch_block))
+ (ExprCatch { block: catch_block }.into())
));
fn arm_requires_comma(arm: &Arm) -> bool {
- if let ExprKind::Block(Unsafety::Normal, _) = arm.body.node {
+ if let ExprKind::Block(ExprBlock { unsafety: Unsafety::Normal, .. }) = arm.body.node {
false
} else {
true
@@ -705,7 +878,12 @@
guard: option!(preceded!(keyword!("if"), expr)) >>
punct!("=>") >>
body: alt!(
- map!(block, |blk| ExprKind::Block(Unsafety::Normal, blk).into())
+ map!(block, |blk| {
+ ExprKind::Block(ExprBlock {
+ unsafety: Unsafety::Normal,
+ block: blk,
+ }).into()
+ })
|
expr
) >>
@@ -727,26 +905,32 @@
punct!("->") >>
ty: ty >>
body: block >>
- (FunctionRetTy::Ty(ty), ExprKind::Block(Unsafety::Normal, body).into())
+ (FunctionRetTy::Ty(ty), ExprKind::Block(ExprBlock {
+ unsafety: Unsafety::Normal,
+ block: body,
+ }).into())
)
|
map!(ambiguous_expr!(allow_struct), |e| (FunctionRetTy::Default, e))
) >>
- (ExprKind::Closure(
- capture,
- Box::new(FnDecl {
+ (ExprClosure {
+ capture: capture,
+ decl: Box::new(FnDecl {
inputs: inputs,
output: ret_and_body.0,
variadic: false,
}),
- Box::new(ret_and_body.1),
- ))
+ body: Box::new(ret_and_body.1),
+ }.into())
));
named!(closure_arg -> FnArg, do_parse!(
pat: pat >>
ty: option!(preceded!(punct!(":"), ty)) >>
- (FnArg::Captured(pat, ty.unwrap_or(Ty::Infer)))
+ (ArgCaptured {
+ pat: pat,
+ ty: ty.unwrap_or_else(|| TyInfer {}.into()),
+ }.into())
));
named!(expr_while -> ExprKind, do_parse!(
@@ -755,37 +939,37 @@
cond: cond >>
while_block: block >>
(match cond {
- Cond::Let(pat, expr) => ExprKind::WhileLet(
- Box::new(pat),
- Box::new(expr),
- while_block,
- lbl,
- ),
- Cond::Expr(cond) => ExprKind::While(
- Box::new(cond),
- while_block,
- lbl,
- ),
+ Cond::Let(pat, expr) => ExprWhileLet {
+ pat: Box::new(pat),
+ expr: Box::new(expr),
+ body: while_block,
+ label: lbl,
+ }.into(),
+ Cond::Expr(cond) => ExprWhile {
+ cond: Box::new(cond),
+ body: while_block,
+ label: lbl,
+ }.into(),
})
));
named!(expr_continue -> ExprKind, do_parse!(
keyword!("continue") >>
lbl: option!(label) >>
- (ExprKind::Continue(lbl))
+ (ExprContinue { 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)) >>
- (ExprKind::Break(lbl, val.map(Box::new)))
+ (ExprBreak { label: lbl, expr: val.map(Box::new) }.into())
));
named_ambiguous_expr!(expr_ret -> ExprKind, allow_struct, do_parse!(
keyword!("return") >>
ret_value: option!(ambiguous_expr!(allow_struct)) >>
- (ExprKind::Ret(ret_value.map(Box::new)))
+ (ExprRet { expr: ret_value.map(Box::new) }.into())
));
named!(expr_struct -> ExprKind, do_parse!(
@@ -800,7 +984,11 @@
)) >>
cond!(!fields.is_empty() && base.is_none(), option!(punct!(","))) >>
punct!("}") >>
- (ExprKind::Struct(path, fields, base.map(Box::new)))
+ (ExprStruct {
+ path: path,
+ fields: fields,
+ rest: base.map(Box::new),
+ }.into())
));
named!(field_value -> FieldValue, alt!(
@@ -818,7 +1006,7 @@
|
map!(ident, |name: Ident| FieldValue {
ident: name.clone(),
- expr: ExprKind::Path(None, name.into()).into(),
+ expr: ExprKind::Path(ExprPath { qself: None, path: name.into() }).into(),
is_shorthand: true,
attrs: Vec::new(),
})
@@ -830,21 +1018,22 @@
punct!(";") >>
times: expr >>
punct!("]") >>
- (ExprKind::Repeat(Box::new(value), Box::new(times)))
+ (ExprRepeat { expr: Box::new(value), amt: Box::new(times) }.into())
));
named!(expr_block -> ExprKind, do_parse!(
rules: unsafety >>
b: block >>
- (ExprKind::Block(rules, Block {
- stmts: b.stmts,
- }))
+ (ExprBlock {
+ unsafety: rules,
+ block: Block { stmts: b.stmts },
+ }.into())
));
named_ambiguous_expr!(expr_range -> ExprKind, allow_struct, do_parse!(
limits: range_limits >>
hi: option!(ambiguous_expr!(allow_struct)) >>
- (ExprKind::Range(None, hi.map(Box::new), limits))
+ (ExprRange { from: None, to: hi.map(Box::new), limits: limits }.into())
));
named!(range_limits -> RangeLimits, alt!(
@@ -853,13 +1042,15 @@
punct!("..") => { |_| RangeLimits::HalfOpen }
));
- named!(expr_path -> ExprKind, map!(qpath, |(qself, path)| ExprKind::Path(qself, path)));
+ named!(expr_path -> ExprKind, map!(qpath, |(qself, path)| {
+ ExprPath { qself: qself, path: path }.into()
+ }));
named_ambiguous_expr!(expr_addr_of -> ExprKind, allow_struct, do_parse!(
punct!("&") >>
mutability: mutability >>
expr: ambiguous_expr!(allow_struct) >>
- (ExprKind::AddrOf(mutability, Box::new(expr)))
+ (ExprAddrOf { mutbl: mutability, expr: Box::new(expr) }.into())
));
named_ambiguous_expr!(and_assign -> Expr, allow_struct, preceded!(
@@ -961,14 +1152,14 @@
fn requires_semi(e: &Expr) -> bool {
match e.node {
- ExprKind::If(_, _, _) |
- ExprKind::IfLet(_, _, _, _) |
- ExprKind::While(_, _, _) |
- ExprKind::WhileLet(_, _, _, _) |
- ExprKind::ForLoop(_, _, _, _) |
- ExprKind::Loop(_, _) |
- ExprKind::Match(_, _) |
- ExprKind::Block(_, _) => false,
+ ExprKind::If(_) |
+ ExprKind::IfLet(_) |
+ ExprKind::While(_) |
+ ExprKind::WhileLet(_) |
+ ExprKind::ForLoop(_) |
+ ExprKind::Loop(_) |
+ ExprKind::Match(_) |
+ ExprKind::Block(_) => false,
_ => true,
}
@@ -1146,7 +1337,7 @@
named!(pat_lit -> Pat, do_parse!(
lit: pat_lit_expr >>
- (if let ExprKind::Path(_, _) = lit.node {
+ (if let ExprKind::Path(_) = lit.node {
return IResult::Error; // these need to be parsed by pat_path
} else {
Pat::Lit(Box::new(lit))
@@ -1165,10 +1356,13 @@
v: alt!(
lit => { ExprKind::Lit }
|
- path => { |p| ExprKind::Path(None, p) }
+ path => { |p| ExprPath { qself: None, path: p }.into() }
) >>
(if neg.is_some() {
- ExprKind::Unary(UnOp::Neg, Box::new(v.into())).into()
+ ExprKind::Unary(ExprUnary {
+ op: UnOp::Neg,
+ expr: Box::new(v.into())
+ }).into()
} else {
v.into()
})
@@ -1213,279 +1407,384 @@
#[cfg(feature = "printing")]
mod printing {
use super::*;
- use {FnArg, FunctionRetTy, Mutability, Ty, Unsafety};
+ use {FnArg, FunctionRetTy, Mutability, Ty, Unsafety, ArgCaptured};
use attr::FilterAttrs;
use quote::{Tokens, ToTokens};
impl ToTokens for Expr {
fn to_tokens(&self, tokens: &mut Tokens) {
tokens.append_all(self.attrs.outer());
- match self.node {
- ExprKind::Box(ref inner) => {
- tokens.append("box");
- inner.to_tokens(tokens);
+ self.node.to_tokens(tokens)
+ }
+ }
+
+ impl ToTokens for ExprBox {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ tokens.append("box");
+ self.expr.to_tokens(tokens);
+ }
+ }
+
+ impl ToTokens for ExprInPlace {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ tokens.append("in");
+ self.place.to_tokens(tokens);
+ self.value.to_tokens(tokens);
+ }
+ }
+
+ impl ToTokens for ExprArray {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ tokens.append("[");
+ tokens.append_separated(&self.exprs, ",");
+ tokens.append("]");
+ }
+ }
+
+ 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(")");
+ }
+ }
+
+ impl ToTokens for ExprMethodCall {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ self.args[0].to_tokens(tokens);
+ tokens.append(".");
+ 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(")");
+ }
+ }
+
+ 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(")");
+ }
+ }
+
+ impl ToTokens for ExprBinary {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ self.left.to_tokens(tokens);
+ self.op.to_tokens(tokens);
+ self.right.to_tokens(tokens);
+ }
+ }
+
+ impl ToTokens for ExprUnary {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ self.op.to_tokens(tokens);
+ self.expr.to_tokens(tokens);
+ }
+ }
+
+ impl ToTokens for ExprCast {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ self.expr.to_tokens(tokens);
+ tokens.append("as");
+ self.ty.to_tokens(tokens);
+ }
+ }
+
+ impl ToTokens for ExprType {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ self.expr.to_tokens(tokens);
+ tokens.append(":");
+ self.ty.to_tokens(tokens);
+ }
+ }
+
+ impl ToTokens for ExprIf {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ tokens.append("if");
+ 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);
+ }
+ }
+ }
+
+ impl ToTokens for ExprIfLet {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ tokens.append("if");
+ tokens.append("let");
+ self.pat.to_tokens(tokens);
+ tokens.append("=");
+ 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);
+ }
+ }
+ }
+
+ 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.cond.to_tokens(tokens);
+ self.body.to_tokens(tokens);
+ }
+ }
+
+ 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.pat.to_tokens(tokens);
+ tokens.append("=");
+ self.expr.to_tokens(tokens);
+ self.body.to_tokens(tokens);
+ }
+ }
+
+ 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.pat.to_tokens(tokens);
+ tokens.append("in");
+ self.expr.to_tokens(tokens);
+ self.body.to_tokens(tokens);
+ }
+ }
+
+ 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.body.to_tokens(tokens);
+ }
+ }
+
+ impl ToTokens for ExprMatch {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ tokens.append("match");
+ self.expr.to_tokens(tokens);
+ tokens.append("{");
+ tokens.append_all(&self.arms);
+ tokens.append("}");
+ }
+ }
+
+ impl ToTokens for ExprCatch {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ tokens.append("do");
+ tokens.append("catch");
+ self.block.to_tokens(tokens);
+ }
+ }
+
+ 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(",");
}
- ExprKind::InPlace(ref place, ref value) => {
- tokens.append("in");
- place.to_tokens(tokens);
- value.to_tokens(tokens);
- }
- ExprKind::Array(ref tys) => {
- tokens.append("[");
- tokens.append_separated(tys, ",");
- tokens.append("]");
- }
- ExprKind::Call(ref func, ref args) => {
- func.to_tokens(tokens);
- tokens.append("(");
- tokens.append_separated(args, ",");
- tokens.append(")");
- }
- ExprKind::MethodCall(ref ident, ref ascript, ref args) => {
- args[0].to_tokens(tokens);
- tokens.append(".");
- ident.to_tokens(tokens);
- if !ascript.is_empty() {
- tokens.append("::");
- tokens.append("<");
- tokens.append_separated(ascript, ",");
- tokens.append(">");
+ match *input {
+ FnArg::Captured(ArgCaptured { ref pat, ty: Ty::Infer(_) }) => {
+ pat.to_tokens(tokens);
}
- tokens.append("(");
- tokens.append_separated(&args[1..], ",");
- tokens.append(")");
- }
- ExprKind::Tup(ref fields) => {
- tokens.append("(");
- tokens.append_separated(fields, ",");
- if fields.len() == 1 {
- tokens.append(",");
- }
- tokens.append(")");
- }
- ExprKind::Binary(op, ref left, ref right) => {
- left.to_tokens(tokens);
- op.to_tokens(tokens);
- right.to_tokens(tokens);
- }
- ExprKind::Unary(op, ref expr) => {
- op.to_tokens(tokens);
- expr.to_tokens(tokens);
- }
- ExprKind::Lit(ref lit) => lit.to_tokens(tokens),
- ExprKind::Cast(ref expr, ref ty) => {
- expr.to_tokens(tokens);
- tokens.append("as");
- ty.to_tokens(tokens);
- }
- ExprKind::Type(ref expr, ref ty) => {
- expr.to_tokens(tokens);
- tokens.append(":");
- ty.to_tokens(tokens);
- }
- ExprKind::If(ref cond, ref then_block, ref else_block) => {
- tokens.append("if");
- cond.to_tokens(tokens);
- then_block.to_tokens(tokens);
- if let Some(ref else_block) = *else_block {
- tokens.append("else");
- else_block.to_tokens(tokens);
- }
- }
- ExprKind::IfLet(ref pat, ref expr, ref then_block, ref else_block) => {
- tokens.append("if");
- tokens.append("let");
- pat.to_tokens(tokens);
- tokens.append("=");
- expr.to_tokens(tokens);
- then_block.to_tokens(tokens);
- if let Some(ref else_block) = *else_block {
- tokens.append("else");
- else_block.to_tokens(tokens);
- }
- }
- ExprKind::While(ref cond, ref body, ref label) => {
- if let Some(ref label) = *label {
- label.to_tokens(tokens);
- tokens.append(":");
- }
- tokens.append("while");
- cond.to_tokens(tokens);
- body.to_tokens(tokens);
- }
- ExprKind::WhileLet(ref pat, ref expr, ref body, ref label) => {
- if let Some(ref label) = *label {
- label.to_tokens(tokens);
- tokens.append(":");
- }
- tokens.append("while");
- tokens.append("let");
- pat.to_tokens(tokens);
- tokens.append("=");
- expr.to_tokens(tokens);
- body.to_tokens(tokens);
- }
- ExprKind::ForLoop(ref pat, ref expr, ref body, ref label) => {
- if let Some(ref label) = *label {
- label.to_tokens(tokens);
- tokens.append(":");
- }
- tokens.append("for");
- pat.to_tokens(tokens);
- tokens.append("in");
- expr.to_tokens(tokens);
- body.to_tokens(tokens);
- }
- ExprKind::Loop(ref body, ref label) => {
- if let Some(ref label) = *label {
- label.to_tokens(tokens);
- tokens.append(":");
- }
- tokens.append("loop");
- body.to_tokens(tokens);
- }
- ExprKind::Match(ref expr, ref arms) => {
- tokens.append("match");
- expr.to_tokens(tokens);
- tokens.append("{");
- tokens.append_all(arms);
- tokens.append("}");
- }
- ExprKind::Catch(ref body) => {
- tokens.append("do");
- tokens.append("catch");
- body.to_tokens(tokens);
- }
- ExprKind::Closure(capture, ref decl, ref expr) => {
- capture.to_tokens(tokens);
- tokens.append("|");
- for (i, input) in decl.inputs.iter().enumerate() {
- if i > 0 {
- tokens.append(",");
- }
- match *input {
- FnArg::Captured(ref pat, Ty::Infer) => {
- pat.to_tokens(tokens);
- }
- _ => input.to_tokens(tokens),
- }
- }
- tokens.append("|");
- match decl.output {
- FunctionRetTy::Default => { /* nothing */ }
- FunctionRetTy::Ty(ref ty) => {
- tokens.append("->");
- ty.to_tokens(tokens);
- }
- }
- expr.to_tokens(tokens);
- }
- ExprKind::Block(rules, ref block) => {
- rules.to_tokens(tokens);
- block.to_tokens(tokens);
- }
- ExprKind::Assign(ref var, ref expr) => {
- var.to_tokens(tokens);
- tokens.append("=");
- expr.to_tokens(tokens);
- }
- ExprKind::AssignOp(op, ref var, ref expr) => {
- var.to_tokens(tokens);
- tokens.append(op.assign_op().unwrap());
- expr.to_tokens(tokens);
- }
- ExprKind::Field(ref expr, ref field) => {
- expr.to_tokens(tokens);
- tokens.append(".");
- field.to_tokens(tokens);
- }
- ExprKind::TupField(ref expr, field) => {
- expr.to_tokens(tokens);
- tokens.append(".");
- tokens.append(&field.to_string());
- }
- ExprKind::Index(ref expr, ref index) => {
- expr.to_tokens(tokens);
- tokens.append("[");
- index.to_tokens(tokens);
- tokens.append("]");
- }
- ExprKind::Range(ref from, ref to, limits) => {
- from.to_tokens(tokens);
- limits.to_tokens(tokens);
- to.to_tokens(tokens);
- }
- ExprKind::Path(None, ref path) => path.to_tokens(tokens),
- ExprKind::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);
- }
- }
- ExprKind::AddrOf(mutability, ref expr) => {
- tokens.append("&");
- mutability.to_tokens(tokens);
- expr.to_tokens(tokens);
- }
- ExprKind::Break(ref opt_label, ref opt_val) => {
- tokens.append("break");
- opt_label.to_tokens(tokens);
- opt_val.to_tokens(tokens);
- }
- ExprKind::Continue(ref opt_label) => {
- tokens.append("continue");
- opt_label.to_tokens(tokens);
- }
- ExprKind::Ret(ref opt_expr) => {
- tokens.append("return");
- opt_expr.to_tokens(tokens);
- }
- ExprKind::Mac(ref mac) => mac.to_tokens(tokens),
- ExprKind::Struct(ref path, ref fields, ref base) => {
- path.to_tokens(tokens);
- tokens.append("{");
- tokens.append_separated(fields, ",");
- if let Some(ref base) = *base {
- if !fields.is_empty() {
- tokens.append(",");
- }
- tokens.append("..");
- base.to_tokens(tokens);
- }
- tokens.append("}");
- }
- ExprKind::Repeat(ref expr, ref times) => {
- tokens.append("[");
- expr.to_tokens(tokens);
- tokens.append(";");
- times.to_tokens(tokens);
- tokens.append("]");
- }
- ExprKind::Paren(ref expr) => {
- tokens.append("(");
- expr.to_tokens(tokens);
- tokens.append(")");
- }
- ExprKind::Try(ref expr) => {
- expr.to_tokens(tokens);
- tokens.append("?");
+ _ => input.to_tokens(tokens),
}
}
+ tokens.append("|");
+ match self.decl.output {
+ FunctionRetTy::Default => { /* nothing */ }
+ FunctionRetTy::Ty(ref ty) => {
+ tokens.append("->");
+ ty.to_tokens(tokens);
+ }
+ }
+ self.body.to_tokens(tokens);
+ }
+ }
+
+ impl ToTokens for ExprBlock {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ self.unsafety.to_tokens(tokens);
+ self.block.to_tokens(tokens);
+ }
+ }
+
+ impl ToTokens for ExprAssign {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ self.left.to_tokens(tokens);
+ tokens.append("=");
+ self.right.to_tokens(tokens);
+ }
+ }
+
+ impl ToTokens for ExprAssignOp {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ self.left.to_tokens(tokens);
+ tokens.append(self.op.assign_op().unwrap());
+ self.right.to_tokens(tokens);
+ }
+ }
+
+ impl ToTokens for ExprField {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ self.expr.to_tokens(tokens);
+ tokens.append(".");
+ self.field.to_tokens(tokens);
+ }
+ }
+
+ impl ToTokens for ExprTupField {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ self.expr.to_tokens(tokens);
+ tokens.append(".");
+ tokens.append(&self.field.to_string());
+ }
+ }
+
+ 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("]");
+ }
+ }
+
+ impl ToTokens for ExprRange {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ self.from.to_tokens(tokens);
+ self.limits.to_tokens(tokens);
+ self.to.to_tokens(tokens);
+ }
+ }
+
+ 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);
+ }
+ }
+ }
+
+ impl ToTokens for ExprAddrOf {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ tokens.append("&");
+ self.mutbl.to_tokens(tokens);
+ self.expr.to_tokens(tokens);
+ }
+ }
+
+ impl ToTokens for ExprBreak {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ tokens.append("break");
+ self.label.to_tokens(tokens);
+ self.expr.to_tokens(tokens);
+ }
+ }
+
+ impl ToTokens for ExprContinue {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ tokens.append("continue");
+ self.label.to_tokens(tokens);
+ }
+ }
+
+ impl ToTokens for ExprRet {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ tokens.append("return");
+ self.expr.to_tokens(tokens);
+ }
+ }
+
+ 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("}");
+ }
+ }
+
+ 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("]");
+ }
+ }
+
+ impl ToTokens for ExprParen {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ tokens.append("(");
+ self.expr.to_tokens(tokens);
+ tokens.append(")");
+ }
+ }
+
+ impl ToTokens for ExprTry {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ self.expr.to_tokens(tokens);
+ tokens.append("?");
}
}
@@ -1512,7 +1811,7 @@
tokens.append("=>");
self.body.to_tokens(tokens);
match self.body.node {
- ExprKind::Block(Unsafety::Normal, _) => {
+ ExprKind::Block(ExprBlock { unsafety: Unsafety::Normal, .. }) => {
// no comma
}
_ => tokens.append(","),
diff --git a/src/fold.rs b/src/fold.rs
index def73f2..3a5c763 100644
--- a/src/fold.rs
+++ b/src/fold.rs
@@ -198,59 +198,89 @@
}
pub fn noop_fold_ty<F: ?Sized + Folder>(folder: &mut F, ty: Ty) -> Ty {
+ use ty::*;
use Ty::*;
+
match ty {
- Slice(inner) => Slice(inner.lift(|v| folder.fold_ty(v))),
- Paren(inner) => Paren(inner.lift(|v| folder.fold_ty(v))),
- Ptr(mutable_type) => {
- let mutable_type_ = *mutable_type;
- let MutTy { ty, mutability }: MutTy = mutable_type_;
- Ptr(Box::new(MutTy {
- ty: folder.fold_ty(ty),
- mutability: mutability,
- }))
+ Slice(TySlice { ty }) => {
+ Slice(TySlice {
+ ty: ty.lift(|v| folder.fold_ty(v)),
+ })
}
- Rptr(opt_lifetime, mutable_type) => {
- let mutable_type_ = *mutable_type;
- let MutTy { ty, mutability }: MutTy = mutable_type_;
- Rptr(opt_lifetime.map(|l| folder.fold_lifetime(l)),
- Box::new(MutTy {
- ty: folder.fold_ty(ty),
- mutability: mutability,
- }))
+ Paren(TyParen { ty }) => {
+ Paren(TyParen {
+ ty: ty.lift(|v| folder.fold_ty(v)),
+ })
}
- Never => Never,
- Infer => Infer,
- Tup(tuple_element_types) => Tup(tuple_element_types.lift(|x| folder.fold_ty(x))),
- BareFn(bare_fn) => {
- let bf_ = *bare_fn;
- let BareFnTy { unsafety, abi, lifetimes, inputs, output, variadic } = bf_;
- BareFn(Box::new(BareFnTy {
- unsafety: unsafety,
- abi: abi,
- lifetimes: lifetimes.lift(|l| folder.fold_lifetime_def(l)),
- inputs: inputs.lift(|v| {
- BareFnArg {
- name: v.name.map(|n| folder.fold_ident(n)),
- ty: folder.fold_ty(v.ty),
- }
- }),
- output: folder.fold_fn_ret_ty(output),
- variadic: variadic,
- }))
+ Ptr(TyPtr { ty }) => {
+ let ty = *ty;
+ let MutTy { ty, mutability } = ty;
+ Ptr(TyPtr {
+ ty: Box::new(MutTy {
+ ty: folder.fold_ty(ty),
+ mutability: mutability,
+ }),
+ })
}
- Path(maybe_qself, path) => {
- Path(maybe_qself.map(|v| noop_fold_qself(folder, v)),
- folder.fold_path(path))
+ Rptr(TyRptr { lifetime, ty }) => {
+ let ty = *ty;
+ let MutTy { ty, mutability } = ty;
+ Rptr(TyRptr {
+ lifetime: lifetime.map(|l| folder.fold_lifetime(l)),
+ ty: Box::new(MutTy {
+ ty: folder.fold_ty(ty),
+ mutability: mutability,
+ }),
+ })
}
- Array(inner, len) => {
- Array({
- inner.lift(|v| folder.fold_ty(v))
- },
- folder.fold_const_expr(len))
+ Never(t) => Never(t),
+ Infer(t) => Infer(t),
+ Tup(TyTup { tys }) => {
+ Tup(TyTup {
+ tys: tys.lift(|x| folder.fold_ty(x)),
+ })
}
- TraitObject(bounds) => TraitObject(bounds.lift(|v| folder.fold_ty_param_bound(v))),
- ImplTrait(bounds) => ImplTrait(bounds.lift(|v| folder.fold_ty_param_bound(v))),
+ BareFn(TyBareFn { ty }) => {
+ let ty = *ty;
+ let BareFnTy { unsafety, abi, lifetimes, inputs, output, variadic } = ty;
+ BareFn(TyBareFn {
+ ty: Box::new(BareFnTy {
+ unsafety: unsafety,
+ abi: abi,
+ lifetimes: lifetimes.lift(|l| folder.fold_lifetime_def(l)),
+ inputs: inputs.lift(|v| {
+ BareFnArg {
+ name: v.name.map(|n| folder.fold_ident(n)),
+ ty: folder.fold_ty(v.ty),
+ }
+ }),
+ output: folder.fold_fn_ret_ty(output),
+ variadic: variadic,
+ }),
+ })
+ }
+ Path(TyPath { qself, path }) => {
+ Path(TyPath {
+ qself: qself.map(|v| noop_fold_qself(folder, v)),
+ path: folder.fold_path(path),
+ })
+ }
+ Array(TyArray { ty, amt }) => {
+ Array(TyArray {
+ ty: ty.lift(|v| folder.fold_ty(v)),
+ amt: folder.fold_const_expr(amt),
+ })
+ }
+ TraitObject(TyTraitObject { bounds }) => {
+ TraitObject(TyTraitObject {
+ bounds: bounds.lift(|v| folder.fold_ty_param_bound(v)),
+ })
+ }
+ ImplTrait(TyImplTrait { bounds }) => {
+ ImplTrait(TyImplTrait {
+ bounds: bounds.lift(|v| folder.fold_ty_param_bound(v)),
+ })
+ }
Mac(mac) => Mac(folder.fold_mac(mac)),
}
}
@@ -435,29 +465,48 @@
}
pub fn noop_fold_const_expr<F: ?Sized + Folder>(folder: &mut F, expr: ConstExpr) -> ConstExpr {
- use ConstExpr::*;
+ use constant::*;
+ use constant::ConstExpr::*;
+
match expr {
- Call(f, args) => {
- Call(f.lift(|e| folder.fold_const_expr(e)),
- args.lift(|v| folder.fold_const_expr(v)))
+ Call(ConstCall { func, args }) => {
+ Call(ConstCall {
+ func: func.lift(|e| folder.fold_const_expr(e)),
+ args: args.lift(|v| folder.fold_const_expr(v)),
+ })
}
- Binary(op, lhs, rhs) => {
- Binary(op,
- lhs.lift(|e| folder.fold_const_expr(e)),
- rhs.lift(|e| folder.fold_const_expr(e)))
+ Binary(ConstBinary { op, left, right }) => {
+ Binary(ConstBinary {
+ op: op,
+ left: left.lift(|e| folder.fold_const_expr(e)),
+ right: right.lift(|e| folder.fold_const_expr(e)),
+ })
}
- Unary(op, e) => Unary(op, e.lift(|e| folder.fold_const_expr(e))),
+ Unary(ConstUnary { op, expr }) => {
+ Unary(ConstUnary {
+ op: op,
+ expr: expr.lift(|e| folder.fold_const_expr(e)),
+ })
+ }
Lit(l) => Lit(folder.fold_lit(l)),
- Cast(e, ty) => {
- Cast(e.lift(|e| folder.fold_const_expr(e)),
- ty.lift(|v| folder.fold_ty(v)))
+ Cast(ConstCast { expr, ty }) => {
+ Cast(ConstCast {
+ expr: expr.lift(|e| folder.fold_const_expr(e)),
+ ty: ty.lift(|v| folder.fold_ty(v)),
+ })
}
Path(p) => Path(folder.fold_path(p)),
- Index(o, i) => {
- Index(o.lift(|e| folder.fold_const_expr(e)),
- i.lift(|e| folder.fold_const_expr(e)))
+ Index(ConstIndex { expr, index }) => {
+ Index(ConstIndex {
+ expr: expr.lift(|e| folder.fold_const_expr(e)),
+ index: index.lift(|e| folder.fold_const_expr(e)),
+ })
}
- Paren(no_op) => Paren(no_op.lift(|e| folder.fold_const_expr(e))),
+ Paren(ConstParen { expr }) => {
+ Paren(ConstParen {
+ expr: expr.lift(|e| folder.fold_const_expr(e)),
+ })
+ }
Other(e) => Other(noop_fold_other_const_expr(folder, e)),
}
}
@@ -537,70 +586,113 @@
pub fn noop_fold_item<F: ?Sized + Folder>(folder: &mut F,
Item { ident, vis, attrs, node }: Item)
-> Item {
+ use item::*;
use ItemKind::*;
Item {
ident: folder.fold_ident(ident.clone()),
vis: noop_fold_vis(folder, vis),
attrs: attrs.lift(|a| folder.fold_attribute(a)),
node: match node {
- ExternCrate(name) => ExternCrate(name.map(|i| folder.fold_ident(i))),
- Use(view_path) => Use(Box::new(folder.fold_view_path(*view_path))),
- Static(ty, mutability, expr) => {
- Static(Box::new(folder.fold_ty(*ty)),
- mutability,
- expr.lift(|e| folder.fold_expr(e)))
+ ExternCrate(ItemExternCrate { original }) => {
+ ExternCrate(ItemExternCrate {
+ original: original.map(|i| folder.fold_ident(i)),
+ })
}
- Const(ty, expr) => {
- Const(ty.lift(|ty| folder.fold_ty(ty)),
- expr.lift(|e| folder.fold_expr(e)))
+ Use(ItemUse { path }) => {
+ Use(ItemUse {
+ path: Box::new(folder.fold_view_path(*path)),
+ })
}
- Fn(fn_decl, unsafety, constness, abi, generics, block) => {
- Fn(fn_decl.lift(|v| folder.fold_fn_decl(v)),
- unsafety,
- constness,
- abi,
- folder.fold_generics(generics),
- block.lift(|v| folder.fold_block(v)))
+ Static(ItemStatic { ty, mutbl, expr }) => {
+ Static(ItemStatic {
+ ty: Box::new(folder.fold_ty(*ty)),
+ mutbl: mutbl,
+ expr: expr.lift(|e| folder.fold_expr(e)),
+ })
}
- Mod(items) => Mod(items.map(|items| items.lift(|i| folder.fold_item(i)))),
- ForeignMod(super::ForeignMod { abi, items }) => {
- ForeignMod(super::ForeignMod {
- abi: abi,
- items: items.lift(|foreign_item| {
- folder.fold_foreign_item(foreign_item)
- }),
- })
+ Const(ItemConst { ty, expr }) => {
+ Const(ItemConst {
+ ty: ty.lift(|ty| folder.fold_ty(ty)),
+ expr: expr.lift(|e| folder.fold_expr(e)),
+ })
}
- Ty(ty, generics) => {
- Ty(ty.lift(|ty| folder.fold_ty(ty)),
- folder.fold_generics(generics))
+ Fn(ItemFn { decl, unsafety, constness, abi, generics, block }) => {
+ 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)),
+ })
}
- Enum(variants, generics) => {
- Enum(variants.lift(|v| folder.fold_variant(v)),
- folder.fold_generics(generics))
+ Mod(ItemMod { items }) => {
+ Mod(ItemMod {
+ items: items.map(|items| items.lift(|i| folder.fold_item(i))),
+ })
}
- Struct(variant_data, generics) => {
- Struct(folder.fold_variant_data(variant_data),
- folder.fold_generics(generics))
+ ForeignMod(ItemForeignMod { abi, items }) => {
+ ForeignMod(ItemForeignMod {
+ abi: abi,
+ items: items.lift(|foreign_item| {
+ folder.fold_foreign_item(foreign_item)
+ }),
+ })
}
- Union(variant_data, generics) => {
- Union(folder.fold_variant_data(variant_data),
- folder.fold_generics(generics))
+ Ty(ItemTy { ty, generics }) => {
+ Ty(ItemTy {
+ ty: ty.lift(|ty| folder.fold_ty(ty)),
+ generics: folder.fold_generics(generics),
+ })
}
- Trait(unsafety, generics, typbs, trait_items) => {
- Trait(unsafety,
- folder.fold_generics(generics),
- typbs.lift(|typb| folder.fold_ty_param_bound(typb)),
- trait_items.lift(|ti| folder.fold_trait_item(ti)))
+ Enum(ItemEnum { variants, generics }) => {
+ Enum(ItemEnum {
+ variants: variants.lift(|v| folder.fold_variant(v)),
+ generics: folder.fold_generics(generics),
+ })
}
- DefaultImpl(unsafety, path) => DefaultImpl(unsafety, folder.fold_path(path)),
- Impl(unsafety, impl_polarity, generics, path, ty, impl_items) => {
- Impl(unsafety,
- impl_polarity,
- folder.fold_generics(generics),
- path.map(|p| folder.fold_path(p)),
- ty.lift(|ty| folder.fold_ty(ty)),
- impl_items.lift(|i| folder.fold_impl_item(i)))
+ Struct(ItemStruct { data, generics }) => {
+ Struct(ItemStruct {
+ data: folder.fold_variant_data(data),
+ generics: folder.fold_generics(generics),
+ })
+ }
+ Union(ItemUnion { data, generics }) => {
+ Union(ItemUnion {
+ data: folder.fold_variant_data(data),
+ generics: folder.fold_generics(generics),
+ })
+ }
+ Trait(ItemTrait { unsafety, generics, supertraits, items }) => {
+ 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)),
+ })
+ }
+ DefaultImpl(ItemDefaultImpl { unsafety, path }) => {
+ DefaultImpl(ItemDefaultImpl {
+ unsafety: unsafety,
+ path: folder.fold_path(path),
+ })
+ }
+ Impl(ItemImpl {
+ unsafety,
+ polarity,
+ generics,
+ trait_,
+ self_ty,
+ items,
+ }) => {
+ 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)),
+ })
}
Mac(mac) => Mac(folder.fold_mac(mac)),
},
@@ -609,142 +701,235 @@
#[cfg(feature = "full")]
pub fn noop_fold_expr<F: ?Sized + Folder>(folder: &mut F, Expr { node, attrs }: Expr) -> Expr {
- use ExprKind::*;
+ use expr::*;
+ use expr::ExprKind::*;
+
Expr {
node: match node {
- ExprKind::Box(e) => ExprKind::Box(e.lift(|e| folder.fold_expr(e))),
- InPlace(place, value) => {
- InPlace(place.lift(|e| folder.fold_expr(e)),
- value.lift(|e| folder.fold_expr(e)))
+ Box(ExprBox { expr }) => {
+ Box(ExprBox { expr: expr.lift(|e| folder.fold_expr(e)) })
}
- Array(array) => Array(array.lift(|e| folder.fold_expr(e))),
- Call(function, args) => {
- Call(function.lift(|e| folder.fold_expr(e)),
- args.lift(|e| folder.fold_expr(e)))
+ InPlace(ExprInPlace { place, value }) => {
+ InPlace(ExprInPlace {
+ place: place.lift(|e| folder.fold_expr(e)),
+ value: value.lift(|e| folder.fold_expr(e)),
+ })
}
- MethodCall(method, tys, args) => {
- MethodCall(folder.fold_ident(method),
- tys.lift(|t| folder.fold_ty(t)),
- args.lift(|e| folder.fold_expr(e)))
+ Array(ExprArray { exprs }) => {
+ Array(ExprArray {
+ exprs: exprs.lift(|e| folder.fold_expr(e)),
+ })
}
- Tup(args) => Tup(args.lift(|e| folder.fold_expr(e))),
- Binary(bop, lhs, rhs) => {
- Binary(bop,
- lhs.lift(|e| folder.fold_expr(e)),
- rhs.lift(|e| folder.fold_expr(e)))
+ Call(ExprCall { func, args }) => {
+ Call(ExprCall {
+ func: func.lift(|e| folder.fold_expr(e)),
+ args: args.lift(|e| folder.fold_expr(e)),
+ })
}
- Unary(uop, e) => Unary(uop, e.lift(|e| folder.fold_expr(e))),
+ MethodCall(ExprMethodCall { method, typarams, args }) => {
+ MethodCall(ExprMethodCall {
+ method: folder.fold_ident(method),
+ typarams: typarams.lift(|t| folder.fold_ty(t)),
+ args: args.lift(|e| folder.fold_expr(e)),
+ })
+ }
+ Tup(ExprTup { args }) => {
+ Tup(ExprTup {
+ args: args.lift(|e| folder.fold_expr(e)),
+ })
+ }
+ Binary(ExprBinary { op, left, right }) => {
+ Binary(ExprBinary {
+ op: op,
+ left: left.lift(|e| folder.fold_expr(e)),
+ right: right.lift(|e| folder.fold_expr(e)),
+ })
+ }
+ Unary(ExprUnary { op, expr }) => {
+ Unary(ExprUnary {
+ op: op,
+ expr: expr.lift(|e| folder.fold_expr(e)),
+ })
+ }
Lit(lit) => Lit(folder.fold_lit(lit)),
- Cast(e, ty) => {
- Cast(e.lift(|e| folder.fold_expr(e)),
- ty.lift(|t| folder.fold_ty(t)))
+ Cast(ExprCast { expr, ty }) => {
+ Cast(ExprCast {
+ expr: expr.lift(|e| folder.fold_expr(e)),
+ ty: ty.lift(|t| folder.fold_ty(t)),
+ })
}
- Type(e, ty) => {
- Type(e.lift(|e| folder.fold_expr(e)),
- ty.lift(|t| folder.fold_ty(t)))
+ Type(ExprType { expr, ty }) => {
+ Type(ExprType {
+ expr: expr.lift(|e| folder.fold_expr(e)),
+ ty: ty.lift(|t| folder.fold_ty(t)),
+ })
}
- If(e, if_block, else_block) => {
- If(e.lift(|e| folder.fold_expr(e)),
- folder.fold_block(if_block),
- else_block.map(|v| v.lift(|e| folder.fold_expr(e))))
+ If(ExprIf { cond, if_true, if_false }) => {
+ 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))),
+ })
}
- IfLet(pat, expr, block, else_block) => {
- IfLet(pat.lift(|p| folder.fold_pat(p)),
- expr.lift(|e| folder.fold_expr(e)),
- folder.fold_block(block),
- else_block.map(|v| v.lift(|e| folder.fold_expr(e))))
+ IfLet(ExprIfLet { pat, expr, if_true, if_false }) => {
+ 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))),
+ })
}
- While(e, block, label) => {
- While(e.lift(|e| folder.fold_expr(e)),
- folder.fold_block(block),
- label.map(|i| folder.fold_ident(i)))
+ While(ExprWhile { cond, body, label }) => {
+ While(ExprWhile {
+ cond: cond.lift(|e| folder.fold_expr(e)),
+ body: folder.fold_block(body),
+ label: label.map(|i| folder.fold_ident(i)),
+ })
}
- WhileLet(pat, expr, block, label) => {
- WhileLet(pat.lift(|p| folder.fold_pat(p)),
- expr.lift(|e| folder.fold_expr(e)),
- folder.fold_block(block),
- label.map(|i| folder.fold_ident(i)))
+ WhileLet(ExprWhileLet { pat, expr, body, label }) => {
+ 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)),
+ })
}
- ForLoop(pat, expr, block, label) => {
- ForLoop(pat.lift(|p| folder.fold_pat(p)),
- expr.lift(|e| folder.fold_expr(e)),
- folder.fold_block(block),
- label.map(|i| folder.fold_ident(i)))
+ ForLoop(ExprForLoop { pat, expr, body, label }) => {
+ 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)),
+ })
}
- Loop(block, label) => {
- Loop(folder.fold_block(block),
- label.map(|i| folder.fold_ident(i)))
+ Loop(ExprLoop { body, label }) => {
+ Loop(ExprLoop {
+ body: folder.fold_block(body),
+ label: label.map(|i| folder.fold_ident(i)),
+ })
}
- Match(e, arms) => {
- Match(e.lift(|e| folder.fold_expr(e)),
- arms.lift(|Arm { attrs, pats, guard, body }: 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)),
- }
- }))
+ Match(ExprMatch { expr, arms }) => {
+ Match(ExprMatch {
+ expr: expr.lift(|e| folder.fold_expr(e)),
+ arms: arms.lift(|Arm { attrs, pats, guard, body }: 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)),
+ }
+ })
+ })
}
- Catch(block) => {
- Catch(folder.fold_block(block))
+ Catch(ExprCatch { block }) => {
+ Catch(ExprCatch { block: folder.fold_block(block) })
}
- Closure(capture_by, fn_decl, expr) => {
- Closure(capture_by,
- fn_decl.lift(|v| folder.fold_fn_decl(v)),
- expr.lift(|e| folder.fold_expr(e)))
+ Closure(ExprClosure { capture, decl, body }) => {
+ Closure(ExprClosure {
+ capture: capture,
+ decl: decl.lift(|v| folder.fold_fn_decl(v)),
+ body: body.lift(|e| folder.fold_expr(e)),
+ })
}
- Block(unsafety, block) => Block(unsafety, folder.fold_block(block)),
- Assign(lhs, rhs) => {
- Assign(lhs.lift(|e| folder.fold_expr(e)),
- rhs.lift(|e| folder.fold_expr(e)))
+ Block(ExprBlock { unsafety, block }) => {
+ Block(ExprBlock {
+ unsafety: unsafety,
+ block: folder.fold_block(block),
+ })
}
- AssignOp(bop, lhs, rhs) => {
- AssignOp(bop,
- lhs.lift(|e| folder.fold_expr(e)),
- rhs.lift(|e| folder.fold_expr(e)))
+ Assign(ExprAssign { left, right }) => {
+ Assign(ExprAssign {
+ left: left.lift(|e| folder.fold_expr(e)),
+ right: right.lift(|e| folder.fold_expr(e)),
+ })
}
- Field(expr, name) => Field(expr.lift(|e| folder.fold_expr(e)), folder.fold_ident(name)),
- TupField(expr, index) => TupField(expr.lift(|e| folder.fold_expr(e)), index),
- Index(expr, index) => {
- Index(expr.lift(|e| folder.fold_expr(e)),
- index.lift(|e| folder.fold_expr(e)))
+ AssignOp(ExprAssignOp { op, left, right }) => {
+ AssignOp(ExprAssignOp {
+ op: op,
+ left: left.lift(|e| folder.fold_expr(e)),
+ right: right.lift(|e| folder.fold_expr(e)),
+ })
}
- Range(lhs, rhs, limits) => {
- Range(lhs.map(|v| v.lift(|e| folder.fold_expr(e))),
- rhs.map(|v| v.lift(|e| folder.fold_expr(e))),
- limits)
+ Field(ExprField { expr, field }) => {
+ Field(ExprField {
+ expr: expr.lift(|e| folder.fold_expr(e)),
+ field: folder.fold_ident(field),
+ })
}
- Path(qself, path) => {
- Path(qself.map(|v| noop_fold_qself(folder, v)),
- folder.fold_path(path))
+ TupField(ExprTupField { expr, field }) => {
+ TupField(ExprTupField {
+ expr: expr.lift(|e| folder.fold_expr(e)),
+ field: field,
+ })
}
- AddrOf(mutability, expr) => AddrOf(mutability, expr.lift(|e| folder.fold_expr(e))),
- Break(label, expr) => {
- Break(label.map(|i| folder.fold_ident(i)),
- expr.map(|v| v.lift(|e| folder.fold_expr(e))))
+ Index(ExprIndex { expr, index }) => {
+ Index(ExprIndex {
+ expr: expr.lift(|e| folder.fold_expr(e)),
+ index: index.lift(|e| folder.fold_expr(e)),
+ })
}
- Continue(label) => Continue(label.map(|i| folder.fold_ident(i))),
- Ret(expr) => Ret(expr.map(|v| v.lift(|e| folder.fold_expr(e)))),
- ExprKind::Mac(mac) => ExprKind::Mac(folder.fold_mac(mac)),
- Struct(path, fields, expr) => {
- Struct(folder.fold_path(path),
- fields.lift(|FieldValue { ident, expr, is_shorthand, attrs }: FieldValue| {
- FieldValue {
- ident: folder.fold_ident(ident),
- expr: folder.fold_expr(expr),
- is_shorthand: is_shorthand,
- attrs: attrs.lift(|v| folder.fold_attribute(v)),
- }
- }),
- expr.map(|v| v.lift(|e| folder.fold_expr(e))))
+ Range(ExprRange { from, to, limits }) => {
+ 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,
+ })
}
- Repeat(element, number) => {
- Repeat(element.lift(|e| folder.fold_expr(e)),
- number.lift(|e| folder.fold_expr(e)))
+ Path(ExprPath { qself, path }) => {
+ Path(ExprPath {
+ qself: qself.map(|v| noop_fold_qself(folder, v)),
+ path: folder.fold_path(path),
+ })
}
- Paren(expr) => Paren(expr.lift(|e| folder.fold_expr(e))),
- Try(expr) => Try(expr.lift(|e| folder.fold_expr(e))),
+ AddrOf(ExprAddrOf { mutbl, expr }) => {
+ AddrOf(ExprAddrOf {
+ mutbl: mutbl,
+ expr: expr.lift(|e| folder.fold_expr(e)),
+ })
+ }
+ Break(ExprBreak { label, expr }) => {
+ Break(ExprBreak {
+ label: label.map(|i| folder.fold_ident(i)),
+ expr: expr.map(|v| v.lift(|e| folder.fold_expr(e))),
+ })
+ }
+ Continue(ExprContinue { label }) => {
+ Continue(ExprContinue {
+ label: label.map(|i| folder.fold_ident(i)),
+ })
+ }
+ Ret(ExprRet { expr }) => {
+ Ret(ExprRet {
+ expr: expr.map(|v| v.lift(|e| folder.fold_expr(e))),
+ })
+ }
+ Mac(mac) => Mac(folder.fold_mac(mac)),
+ Struct(ExprStruct { path, fields, rest }) => {
+ Struct(ExprStruct {
+ path: folder.fold_path(path),
+ fields: fields.lift(|FieldValue { ident, expr, is_shorthand, attrs }: FieldValue| {
+ FieldValue {
+ ident: folder.fold_ident(ident),
+ expr: folder.fold_expr(expr),
+ is_shorthand: is_shorthand,
+ attrs: attrs.lift(|v| folder.fold_attribute(v)),
+ }
+ }),
+ rest: rest.map(|v| v.lift(|e| folder.fold_expr(e))),
+ })
+ }
+ Repeat(ExprRepeat { expr, amt }) => {
+ Repeat(ExprRepeat {
+ expr: expr.lift(|e| folder.fold_expr(e)),
+ amt: amt.lift(|e| folder.fold_expr(e)),
+ })
+ }
+ Paren(ExprParen { expr }) => {
+ Paren(ExprParen { expr: expr.lift(|e| folder.fold_expr(e)) })
+ }
+ Try(ExprTry { expr }) => {
+ Try(ExprTry { expr: expr.lift(|e| folder.fold_expr(e)) })
+ }
},
attrs: attrs.into_iter().map(|a| folder.fold_attribute(a)).collect(),
}
@@ -754,16 +939,23 @@
pub fn noop_fold_foreign_item<F: ?Sized + Folder>(folder: &mut F,
ForeignItem { ident, attrs, node, vis }: 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(fn_dcl, generics) => {
- ForeignItemKind::Fn(fn_dcl.lift(|v| folder.fold_fn_decl(v)),
- folder.fold_generics(generics))
+ ForeignItemKind::Fn(ForeignItemFn { decl, generics }) => {
+ ForeignItemKind::Fn(ForeignItemFn {
+ decl: decl.lift(|v| folder.fold_fn_decl(v)),
+ generics: folder.fold_generics(generics),
+ })
}
- ForeignItemKind::Static(ty, mutability) => {
- ForeignItemKind::Static(ty.lift(|v| folder.fold_ty(v)), mutability)
+ ForeignItemKind::Static(ForeignItemStatic { ty, mutbl }) => {
+ ForeignItemKind::Static(ForeignItemStatic {
+ ty: ty.lift(|v| folder.fold_ty(v)),
+ mutbl: mutbl,
+ })
}
},
vis: noop_fold_vis(folder, vis),
@@ -826,13 +1018,26 @@
FnDecl {
inputs: inputs.lift(|a| {
+ use item::*;
use FnArg::*;
match a {
- SelfRef(lifetime, mutability) => {
- SelfRef(lifetime.map(|v| folder.fold_lifetime(v)), mutability)
+ SelfRef(ArgSelfRef { lifetime, mutbl }) => {
+ SelfRef(ArgSelfRef {
+ lifetime: lifetime.map(|v| folder.fold_lifetime(v)),
+ mutbl: mutbl,
+ })
}
- SelfValue(mutability) => SelfValue(mutability),
- Captured(pat, ty) => Captured(folder.fold_pat(pat), folder.fold_ty(ty)),
+ SelfValue(ArgSelf { mutbl } ) => {
+ SelfValue(ArgSelf {
+ mutbl: mutbl,
+ })
+ }
+ Captured(ArgCaptured { pat, ty }) => {
+ Captured(ArgCaptured {
+ pat: folder.fold_pat(pat),
+ ty: folder.fold_ty(ty),
+ })
+ }
Ignored(ty) => Ignored(folder.fold_ty(ty)),
}
}),
@@ -846,19 +1051,29 @@
pub fn noop_fold_trait_item<F: ?Sized + Folder>(folder: &mut F,
TraitItem { ident, attrs, node }: TraitItem)
-> TraitItem {
+ use item::*;
use TraitItemKind::*;
TraitItem {
ident: folder.fold_ident(ident),
attrs: attrs.lift(|v| folder.fold_attribute(v)),
node: match node {
- Const(ty, expr) => Const(folder.fold_ty(ty), expr.map(|v| folder.fold_expr(v))),
- Method(sig, block) => {
- Method(folder.fold_method_sig(sig),
- block.map(|v| folder.fold_block(v)))
+ Const(TraitItemConst { ty, default }) => {
+ Const(TraitItemConst {
+ ty: folder.fold_ty(ty),
+ default: default.map(|v| folder.fold_expr(v)),
+ })
}
- Type(ty_pbs, ty) => {
- Type(ty_pbs.lift(|v| folder.fold_ty_param_bound(v)),
- ty.map(|v| folder.fold_ty(v)))
+ Method(TraitItemMethod { sig, default }) => {
+ Method(TraitItemMethod {
+ sig: folder.fold_method_sig(sig),
+ default: default.map(|v| folder.fold_block(v)),
+ })
+ }
+ Type(TraitItemType { bounds, default }) => {
+ Type(TraitItemType {
+ bounds: bounds.lift(|v| folder.fold_ty_param_bound(v)),
+ default: default.map(|v| folder.fold_ty(v)),
+ })
}
Macro(mac) => Macro(folder.fold_mac(mac)),
},
@@ -869,16 +1084,32 @@
pub fn noop_fold_impl_item<F: ?Sized + Folder>(folder: &mut F,
ImplItem { ident, vis, defaultness, attrs, node }: 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(ty, expr) => Const(folder.fold_ty(ty), folder.fold_expr(expr)),
- Method(sig, block) => Method(folder.fold_method_sig(sig), folder.fold_block(block)),
- Type(ty) => Type(folder.fold_ty(ty)),
+ Const(ImplItemConst { ty, expr }) => {
+ Const(ImplItemConst {
+ ty: folder.fold_ty(ty),
+ expr: folder.fold_expr(expr),
+ })
+ }
+ Method(ImplItemMethod { sig, block }) => {
+ Method(ImplItemMethod {
+ sig: folder.fold_method_sig(sig),
+ block: folder.fold_block(block),
+ })
+ }
+ Type(ImplItemType { ty }) => {
+ Type(ImplItemType {
+ ty: folder.fold_ty(ty),
+ })
+ }
Macro(mac) => Macro(folder.fold_mac(mac)),
},
}
@@ -929,18 +1160,30 @@
#[cfg(feature = "full")]
pub fn noop_fold_view_path<F: ?Sized + Folder>(folder: &mut F, view_path: ViewPath) -> ViewPath {
+ use item::*;
use ViewPath::*;
match view_path {
- Simple(path, ident) => Simple(folder.fold_path(path), ident.map(|i| folder.fold_ident(i))),
- Glob(path) => Glob(folder.fold_path(path)),
- List(path, items) => {
- List(folder.fold_path(path),
- items.lift(|PathListItem { name, rename }: PathListItem| {
- PathListItem {
- name: folder.fold_ident(name),
- rename: rename.map(|i| folder.fold_ident(i)),
- }
- }))
+ Simple(PathSimple { path, rename }) => {
+ Simple(PathSimple {
+ path: folder.fold_path(path),
+ rename: rename.map(|i| folder.fold_ident(i)),
+ })
+ }
+ Glob(PathGlob { path }) => {
+ Glob(PathGlob {
+ path: folder.fold_path(path),
+ })
+ }
+ List(PathList { path, items }) => {
+ List(PathList {
+ path: folder.fold_path(path),
+ items: items.lift(|PathListItem { name, rename }: PathListItem| {
+ PathListItem {
+ name: folder.fold_ident(name),
+ rename: rename.map(|i| folder.fold_ident(i)),
+ }
+ }),
+ })
}
}
}
diff --git a/src/generics.rs b/src/generics.rs
index fbb89b1..2841a47 100644
--- a/src/generics.rs
+++ b/src/generics.rs
@@ -1,12 +1,14 @@
use super::*;
-/// Represents lifetimes and type parameters attached to a declaration
-/// of a function, enum, trait, etc.
-#[derive(Debug, Clone, Eq, PartialEq, Default, Hash)]
-pub struct Generics {
- pub lifetimes: Vec<LifetimeDef>,
- pub ty_params: Vec<TyParam>,
- pub where_clause: WhereClause,
+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 where_clause: WhereClause,
+ }
}
#[cfg(feature = "printing")]
@@ -58,9 +60,10 @@
}
}
-#[derive(Debug, Clone, Eq, PartialEq, Hash, Ord, PartialOrd)]
-pub struct Lifetime {
- pub ident: Ident,
+ast_struct! {
+ pub struct Lifetime {
+ pub ident: Ident,
+ }
}
impl Lifetime {
@@ -75,12 +78,13 @@
}
}
-/// A lifetime definition, e.g. `'a: 'b+'c+'d`
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-pub struct LifetimeDef {
- pub attrs: Vec<Attribute>,
- pub lifetime: Lifetime,
- pub bounds: Vec<Lifetime>,
+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>,
+ }
}
impl LifetimeDef {
@@ -93,13 +97,14 @@
}
}
-/// A generic type parameter, e.g. `T: Into<String>`.
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-pub struct TyParam {
- pub attrs: Vec<Attribute>,
- pub ident: Ident,
- pub bounds: Vec<TyParamBound>,
- pub default: Option<Ty>,
+ast_struct! {
+ /// A generic type parameter, e.g. `T: Into<String>`.
+ pub struct TyParam {
+ pub attrs: Vec<Attribute>,
+ pub ident: Ident,
+ pub bounds: Vec<TyParamBound>,
+ pub default: Option<Ty>,
+ }
}
impl From<Ident> for TyParam {
@@ -113,28 +118,33 @@
}
}
-/// The AST represents all type param bounds as types.
-/// `typeck::collect::compute_bounds` matches these against
-/// the "special" built-in traits (see `middle::lang_items`) and
-/// detects Copy, Send and Sync.
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-pub enum TyParamBound {
- Trait(PolyTraitRef, TraitBoundModifier),
- Region(Lifetime),
+ast_enum! {
+ /// The AST represents all type param bounds as types.
+ /// `typeck::collect::compute_bounds` matches these against
+ /// the "special" built-in traits (see `middle::lang_items`) and
+ /// detects Copy, Send and Sync.
+ pub enum TyParamBound {
+ Trait(PolyTraitRef, TraitBoundModifier),
+ Region(Lifetime),
+ }
}
-/// A modifier on a bound, currently this is only used for `?Sized`, where the
-/// modifier is `Maybe`. Negative bounds should also be handled here.
-#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
-pub enum TraitBoundModifier {
- None,
- Maybe,
+ast_enum! {
+ /// A modifier on a bound, currently this is only used for `?Sized`, where the
+ /// modifier is `Maybe`. Negative bounds should also be handled here.
+ #[derive(Copy)]
+ pub enum TraitBoundModifier {
+ None,
+ Maybe,
+ }
}
-/// A `where` clause in a definition
-#[derive(Debug, Clone, Eq, PartialEq, Default, Hash)]
-pub struct WhereClause {
- pub predicates: Vec<WherePredicate>,
+ast_struct! {
+ /// A `where` clause in a definition
+ #[derive(Default)]
+ pub struct WhereClause {
+ pub predicates: Vec<WherePredicate>,
+ }
}
impl WhereClause {
@@ -143,46 +153,31 @@
}
}
-/// A single predicate in a `where` clause
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-pub enum WherePredicate {
- /// A type binding, e.g. `for<'c> Foo: Send+Clone+'c`
- BoundPredicate(WhereBoundPredicate),
- /// A lifetime predicate, e.g. `'a: 'b+'c`
- RegionPredicate(WhereRegionPredicate),
- /// An equality predicate (unsupported)
- EqPredicate(WhereEqPredicate),
-}
+ast_enum_of_structs! {
+ /// A single predicate in a `where` clause
+ pub enum WherePredicate {
+ /// 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>,
+ /// The type being bounded
+ pub bounded_ty: Ty,
+ /// Trait and lifetime bounds (`Clone+Send+'static`)
+ pub bounds: Vec<TyParamBound>,
+ }),
-/// A type bound.
-///
-/// E.g. `for<'c> Foo: Send+Clone+'c`
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-pub struct WhereBoundPredicate {
- /// Any lifetimes from a `for` binding
- pub bound_lifetimes: Vec<LifetimeDef>,
- /// The type being bounded
- pub bounded_ty: Ty,
- /// Trait and lifetime bounds (`Clone+Send+'static`)
- pub bounds: Vec<TyParamBound>,
-}
+ /// A lifetime predicate, e.g. `'a: 'b+'c`
+ pub RegionPredicate(WhereRegionPredicate {
+ pub lifetime: Lifetime,
+ pub bounds: Vec<Lifetime>,
+ }),
-/// A lifetime predicate.
-///
-/// E.g. `'a: 'b+'c`
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-pub struct WhereRegionPredicate {
- pub lifetime: Lifetime,
- pub bounds: Vec<Lifetime>,
-}
-
-/// An equality predicate (unsupported).
-///
-/// E.g. `T=int`
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-pub struct WhereEqPredicate {
- pub lhs_ty: Ty,
- pub rhs_ty: Ty,
+ /// An equality predicate (unsupported)
+ pub EqPredicate(WhereEqPredicate {
+ pub lhs_ty: Ty,
+ pub rhs_ty: Ty,
+ }),
+ }
}
#[cfg(feature = "parsing")]
@@ -441,8 +436,8 @@
fn to_tokens(&self, tokens: &mut Tokens) {
match *self {
TyParamBound::Region(ref lifetime) => lifetime.to_tokens(tokens),
- TyParamBound::Trait(ref trait_ref, modifier) => {
- match modifier {
+ TyParamBound::Trait(ref trait_ref, ref modifier) => {
+ match *modifier {
TraitBoundModifier::None => {}
TraitBoundModifier::Maybe => tokens.append("?"),
}
@@ -461,22 +456,6 @@
}
}
- impl ToTokens for WherePredicate {
- fn to_tokens(&self, tokens: &mut Tokens) {
- match *self {
- WherePredicate::BoundPredicate(ref predicate) => {
- predicate.to_tokens(tokens);
- }
- WherePredicate::RegionPredicate(ref predicate) => {
- predicate.to_tokens(tokens);
- }
- WherePredicate::EqPredicate(ref predicate) => {
- predicate.to_tokens(tokens);
- }
- }
- }
- }
-
impl ToTokens for WhereBoundPredicate {
fn to_tokens(&self, tokens: &mut Tokens) {
if !self.bound_lifetimes.is_empty() {
diff --git a/src/item.rs b/src/item.rs
index 4cbac33..7b25f2f 100644
--- a/src/item.rs
+++ b/src/item.rs
@@ -1,83 +1,129 @@
use super::*;
-/// An item
-///
-/// The name might be a dummy name in case of anonymous items
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-pub struct Item {
- pub ident: Ident,
- pub vis: Visibility,
- pub attrs: Vec<Attribute>,
- pub node: ItemKind,
+ast_struct! {
+ /// An item
+ ///
+ /// The name might be a dummy name in case of anonymous items
+ pub struct Item {
+ pub ident: Ident,
+ pub vis: Visibility,
+ pub attrs: Vec<Attribute>,
+ pub node: ItemKind,
+ }
}
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-pub enum ItemKind {
- /// An`extern crate` item, with optional original crate name.
- ///
- /// E.g. `extern crate foo` or `extern crate foo_bar as foo`
- ExternCrate(Option<Ident>),
- /// A use declaration (`use` or `pub use`) item.
- ///
- /// E.g. `use foo;`, `use foo::bar;` or `use foo::bar as FooBar;`
- Use(Box<ViewPath>),
- /// A static item (`static` or `pub static`).
- ///
- /// E.g. `static FOO: i32 = 42;` or `static FOO: &'static str = "bar";`
- Static(Box<Ty>, Mutability, Box<Expr>),
- /// A constant item (`const` or `pub const`).
- ///
- /// E.g. `const FOO: i32 = 42;`
- Const(Box<Ty>, Box<Expr>),
- /// A function declaration (`fn` or `pub fn`).
- ///
- /// E.g. `fn foo(bar: usize) -> usize { .. }`
- Fn(Box<FnDecl>, Unsafety, Constness, Option<Abi>, Generics, Box<Block>),
- /// A module declaration (`mod` or `pub mod`).
- ///
- /// E.g. `mod foo;` or `mod foo { .. }`
- Mod(Option<Vec<Item>>),
- /// An external module (`extern` or `pub extern`).
- ///
- /// E.g. `extern {}` or `extern "C" {}`
- ForeignMod(ForeignMod),
- /// A type alias (`type` or `pub type`).
- ///
- /// E.g. `type Foo = Bar<u8>;`
- Ty(Box<Ty>, Generics),
- /// An enum definition (`enum` or `pub enum`).
- ///
- /// E.g. `enum Foo<A, B> { C<A>, D<B> }`
- Enum(Vec<Variant>, Generics),
- /// A struct definition (`struct` or `pub struct`).
- ///
- /// E.g. `struct Foo<A> { x: A }`
- Struct(VariantData, Generics),
- /// A union definition (`union` or `pub union`).
- ///
- /// E.g. `union Foo<A, B> { x: A, y: B }`
- Union(VariantData, Generics),
- /// A Trait declaration (`trait` or `pub trait`).
- ///
- /// E.g. `trait Foo { .. }` or `trait Foo<T> { .. }`
- Trait(Unsafety, Generics, Vec<TyParamBound>, Vec<TraitItem>),
- /// Default trait implementation.
- ///
- /// E.g. `impl Trait for .. {}` or `impl<T> Trait<T> for .. {}`
- DefaultImpl(Unsafety, Path),
- /// An implementation.
- ///
- /// E.g. `impl<A> Foo<A> { .. }` or `impl<A> Trait for Foo<A> { .. }`
- Impl(Unsafety,
- ImplPolarity,
- Generics,
- Option<Path>, // (optional) trait this impl implements
- Box<Ty>, // self
- Vec<ImplItem>),
- /// A macro invocation (which includes macro definition).
- ///
- /// E.g. `macro_rules! foo { .. }` or `foo!(..)`
- Mac(Mac),
+ast_enum_of_structs! {
+ pub enum ItemKind {
+ /// An`extern crate` item, with optional original crate name.
+ ///
+ /// E.g. `extern crate foo` or `extern crate foo_bar as foo`
+ pub ExternCrate(ItemExternCrate {
+ pub original: Option<Ident>,
+ }),
+ /// 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 path: Box<ViewPath>,
+ }),
+ /// A static item (`static` or `pub static`).
+ ///
+ /// E.g. `static FOO: i32 = 42;` or `static FOO: &'static str = "bar";`
+ pub Static(ItemStatic {
+ pub ty: Box<Ty>,
+ pub mutbl: Mutability,
+ pub expr: Box<Expr>,
+ }),
+ /// A constant item (`const` or `pub const`).
+ ///
+ /// E.g. `const FOO: i32 = 42;`
+ pub Const(ItemConst {
+ pub ty: Box<Ty>,
+ pub expr: Box<Expr>,
+ }),
+ /// A function declaration (`fn` or `pub fn`).
+ ///
+ /// E.g. `fn foo(bar: usize) -> usize { .. }`
+ pub Fn(ItemFn {
+ pub decl: Box<FnDecl>,
+ 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>>,
+ }),
+ /// An external module (`extern` or `pub extern`).
+ ///
+ /// E.g. `extern {}` or `extern "C" {}`
+ pub ForeignMod(ItemForeignMod),
+ /// A type alias (`type` or `pub type`).
+ ///
+ /// E.g. `type Foo = Bar<u8>;`
+ pub Ty(ItemTy {
+ pub ty: Box<Ty>,
+ pub generics: Generics,
+ }),
+ /// An enum definition (`enum` or `pub enum`).
+ ///
+ /// E.g. `enum Foo<A, B> { C<A>, D<B> }`
+ pub Enum(ItemEnum {
+ pub variants: Vec<Variant>,
+ pub generics: Generics,
+ }),
+ /// A struct definition (`struct` or `pub struct`).
+ ///
+ /// E.g. `struct Foo<A> { x: A }`
+ pub Struct(ItemStruct {
+ pub data: VariantData,
+ pub generics: Generics,
+ }),
+ /// A union definition (`union` or `pub union`).
+ ///
+ /// E.g. `union Foo<A, B> { x: A, y: B }`
+ pub Union(ItemUnion {
+ pub data: VariantData,
+ pub generics: Generics,
+ }),
+ /// A Trait declaration (`trait` or `pub trait`).
+ ///
+ /// E.g. `trait Foo { .. }` or `trait Foo<T> { .. }`
+ pub Trait(ItemTrait {
+ pub unsafety: Unsafety,
+ pub generics: Generics,
+ pub supertraits: Vec<TyParamBound>,
+ pub items: Vec<TraitItem>,
+ }),
+ /// Default trait implementation.
+ ///
+ /// E.g. `impl Trait for .. {}` or `impl<T> Trait<T> for .. {}`
+ pub DefaultImpl(ItemDefaultImpl {
+ pub unsafety: Unsafety,
+ pub path: Path,
+ }),
+ /// An implementation.
+ ///
+ /// E.g. `impl<A> Foo<A> { .. }` or `impl<A> Trait for Foo<A> { .. }`
+ pub Impl(ItemImpl {
+ pub unsafety: Unsafety,
+ pub polarity: ImplPolarity,
+ pub generics: Generics,
+ pub trait_: Option<Path>, // (optional) trait this impl implements
+ pub self_ty: Box<Ty>, // self
+ pub items: Vec<ImplItem>,
+ }),
+ /// A macro invocation (which includes macro definition).
+ ///
+ /// E.g. `macro_rules! foo { .. }` or `foo!(..)`
+ pub Mac(Mac),
+ }
+
+ do_not_generate_to_tokens
}
impl From<DeriveInput> for Item {
@@ -87,148 +133,221 @@
vis: input.vis,
attrs: input.attrs,
node: match input.body {
- Body::Enum(variants) => ItemKind::Enum(variants, input.generics),
- Body::Struct(variant_data) => ItemKind::Struct(variant_data, input.generics),
+ Body::Enum(variants) => {
+ ItemEnum {
+ variants: variants,
+ generics: input.generics,
+ }.into()
+ }
+ Body::Struct(variant_data) => {
+ ItemStruct {
+ data: variant_data,
+ generics: input.generics,
+ }.into()
+ }
},
}
}
}
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-pub enum ViewPath {
- /// `foo::bar::baz as quux`
+ast_enum_of_structs! {
+ pub enum ViewPath {
+ /// `foo::bar::baz as quux`
+ ///
+ /// or just
+ ///
+ /// `foo::bar::baz` (with `as baz` implicitly on the right)
+ pub Simple(PathSimple {
+ pub path: Path,
+ pub rename: Option<Ident>,
+ }),
+
+ /// `foo::bar::*`
+ pub Glob(PathGlob {
+ pub path: Path,
+ }),
+
+ /// `foo::bar::{a, b, c}`
+ pub List(PathList {
+ pub path: Path,
+ pub items: Vec<PathListItem>,
+ }),
+ }
+}
+
+ast_struct! {
+ pub struct PathListItem {
+ pub name: Ident,
+ /// renamed in list, e.g. `use foo::{bar as baz};`
+ pub rename: Option<Ident>,
+ }
+}
+
+ast_enum! {
+ #[derive(Copy)]
+ pub enum Constness {
+ Const,
+ NotConst,
+ }
+}
+
+ast_enum! {
+ #[derive(Copy)]
+ pub enum Defaultness {
+ Default,
+ Final,
+ }
+}
+
+ast_struct! {
+ /// Foreign module declaration.
///
- /// or just
+ /// 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,
+ }
+}
+
+ast_enum_of_structs! {
+ /// An item within an `extern` block
+ pub enum ForeignItemKind {
+ /// A foreign function
+ pub Fn(ForeignItemFn {
+ pub decl: Box<FnDecl>,
+ pub generics: Generics,
+ }),
+ /// A foreign static item (`static ext: u8`)
+ pub Static(ForeignItemStatic {
+ pub ty: Box<Ty>,
+ pub mutbl: Mutability,
+ }),
+ }
+
+ do_not_generate_to_tokens
+}
+
+ast_struct! {
+ /// Represents an item declaration within a trait declaration,
+ /// possibly including a default implementation. A trait item is
+ /// either required (meaning it doesn't have an implementation, just a
+ /// signature) or provided (meaning it has a default implementation).
+ pub struct TraitItem {
+ pub ident: Ident,
+ pub attrs: Vec<Attribute>,
+ pub node: TraitItemKind,
+ }
+}
+
+ast_enum_of_structs! {
+ pub enum TraitItemKind {
+ pub Const(TraitItemConst {
+ pub ty: Ty,
+ pub default: Option<Expr>,
+ }),
+ pub Method(TraitItemMethod {
+ pub sig: MethodSig,
+ pub default: Option<Block>,
+ }),
+ pub Type(TraitItemType {
+ pub bounds: Vec<TyParamBound>,
+ pub default: Option<Ty>,
+ }),
+ pub Macro(Mac),
+ }
+
+ do_not_generate_to_tokens
+}
+
+ast_enum! {
+ #[derive(Copy)]
+ pub enum ImplPolarity {
+ /// `impl Trait for Type`
+ Positive,
+ /// `impl !Trait for Type`
+ Negative,
+ }
+}
+
+ast_struct! {
+ pub struct ImplItem {
+ pub ident: Ident,
+ pub vis: Visibility,
+ pub defaultness: Defaultness,
+ pub attrs: Vec<Attribute>,
+ pub node: ImplItemKind,
+ }
+}
+
+ast_enum_of_structs! {
+ pub enum ImplItemKind {
+ pub Const(ImplItemConst {
+ pub ty: Ty,
+ pub expr: Expr,
+ }),
+ pub Method(ImplItemMethod {
+ pub sig: MethodSig,
+ pub block: Block,
+ }),
+ pub Type(ImplItemType {
+ pub ty: Ty,
+ }),
+ pub Macro(Mac),
+ }
+
+ do_not_generate_to_tokens
+}
+
+ast_struct! {
+ /// Represents a method's signature in a trait declaration,
+ /// or in an implementation.
+ pub struct MethodSig {
+ pub unsafety: Unsafety,
+ pub constness: Constness,
+ pub abi: Option<Abi>,
+ pub decl: FnDecl,
+ pub generics: Generics,
+ }
+}
+
+ast_struct! {
+ /// Header (not the body) of a function declaration.
///
- /// `foo::bar::baz` (with `as baz` implicitly on the right)
- Simple(Path, Option<Ident>),
-
- /// `foo::bar::*`
- Glob(Path),
-
- /// `foo::bar::{a, b, c}`
- List(Path, Vec<PathListItem>),
+ /// E.g. `fn foo(bar: baz)`
+ pub struct FnDecl {
+ pub inputs: Vec<FnArg>,
+ pub output: FunctionRetTy,
+ pub variadic: bool,
+ }
}
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-pub struct PathListItem {
- pub name: Ident,
- /// renamed in list, e.g. `use foo::{bar as baz};`
- pub rename: Option<Ident>,
-}
-
-#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
-pub enum Constness {
- Const,
- NotConst,
-}
-
-#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
-pub enum Defaultness {
- Default,
- Final,
-}
-
-/// Foreign module declaration.
-///
-/// E.g. `extern { .. }` or `extern "C" { .. }`
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-pub struct ForeignMod {
- pub abi: Abi,
- pub items: Vec<ForeignItem>,
-}
-
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-pub struct ForeignItem {
- pub ident: Ident,
- pub attrs: Vec<Attribute>,
- pub node: ForeignItemKind,
- pub vis: Visibility,
-}
-
-/// An item within an `extern` block
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-pub enum ForeignItemKind {
- /// A foreign function
- Fn(Box<FnDecl>, Generics),
- /// A foreign static item (`static ext: u8`)
- Static(Box<Ty>, Mutability),
-}
-
-/// Represents an item declaration within a trait declaration,
-/// possibly including a default implementation. A trait item is
-/// either required (meaning it doesn't have an implementation, just a
-/// signature) or provided (meaning it has a default implementation).
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-pub struct TraitItem {
- pub ident: Ident,
- pub attrs: Vec<Attribute>,
- pub node: TraitItemKind,
-}
-
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-pub enum TraitItemKind {
- Const(Ty, Option<Expr>),
- Method(MethodSig, Option<Block>),
- Type(Vec<TyParamBound>, Option<Ty>),
- Macro(Mac),
-}
-
-#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
-pub enum ImplPolarity {
- /// `impl Trait for Type`
- Positive,
- /// `impl !Trait for Type`
- Negative,
-}
-
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-pub struct ImplItem {
- pub ident: Ident,
- pub vis: Visibility,
- pub defaultness: Defaultness,
- pub attrs: Vec<Attribute>,
- pub node: ImplItemKind,
-}
-
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-pub enum ImplItemKind {
- Const(Ty, Expr),
- Method(MethodSig, Block),
- Type(Ty),
- Macro(Mac),
-}
-
-/// Represents a method's signature in a trait declaration,
-/// or in an implementation.
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-pub struct MethodSig {
- pub unsafety: Unsafety,
- pub constness: Constness,
- pub abi: Option<Abi>,
- pub decl: FnDecl,
- pub generics: Generics,
-}
-
-/// Header (not the body) of a function declaration.
-///
-/// E.g. `fn foo(bar: baz)`
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-pub struct FnDecl {
- pub inputs: Vec<FnArg>,
- pub output: FunctionRetTy,
- pub variadic: bool,
-}
-
-/// An argument in a function header.
-///
-/// E.g. `bar: usize` as in `fn foo(bar: usize)`
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-pub enum FnArg {
- SelfRef(Option<Lifetime>, Mutability),
- SelfValue(Mutability),
- Captured(Pat, Ty),
- Ignored(Ty),
+ast_enum_of_structs! {
+ /// An argument in a function header.
+ ///
+ /// E.g. `bar: usize` as in `fn foo(bar: usize)`
+ pub enum FnArg {
+ pub SelfRef(ArgSelfRef {
+ pub lifetime: Option<Lifetime>,
+ pub mutbl: Mutability,
+ }),
+ pub SelfValue(ArgSelf {
+ pub mutbl: Mutability,
+ }),
+ pub Captured(ArgCaptured {
+ pub pat: Pat,
+ pub ty: Ty,
+ }),
+ pub Ignored(Ty),
+ }
}
#[cfg(feature = "parsing")]
@@ -319,7 +438,7 @@
ident: name,
vis: vis,
attrs: attrs,
- node: ItemKind::ExternCrate(original_name),
+ node: ItemExternCrate { original: original_name }.into(),
}
})
));
@@ -334,7 +453,7 @@
ident: "".into(),
vis: vis,
attrs: attrs,
- node: ItemKind::Use(Box::new(what)),
+ node: ItemUse { path: Box::new(what) }.into(),
})
));
@@ -352,14 +471,14 @@
named!(view_path_simple -> ViewPath, do_parse!(
path: path >>
rename: option!(preceded!(keyword!("as"), ident)) >>
- (ViewPath::Simple(path, rename))
+ (PathSimple { path: path, rename: rename }.into())
));
named!(view_path_glob -> ViewPath, do_parse!(
path: path >>
punct!("::") >>
punct!("*") >>
- (ViewPath::Glob(path))
+ (PathGlob { path: path }.into())
));
named!(view_path_list -> ViewPath, do_parse!(
@@ -368,7 +487,7 @@
punct!("{") >>
items: terminated_list!(punct!(","), path_list_item) >>
punct!("}") >>
- (ViewPath::List(path, items))
+ (PathList { path: path, items: items }.into())
));
named!(view_path_list_root -> ViewPath, do_parse!(
@@ -376,10 +495,13 @@
punct!("{") >>
items: terminated_list!(punct!(","), path_list_item) >>
punct!("}") >>
- (ViewPath::List(Path {
- global: global.is_some(),
- segments: Vec::new(),
- }, items))
+ (PathList {
+ path: Path {
+ global: global.is_some(),
+ segments: Vec::new(),
+ },
+ items: items,
+ }.into())
));
named!(path_list_item -> PathListItem, do_parse!(
@@ -410,7 +532,11 @@
ident: id,
vis: vis,
attrs: attrs,
- node: ItemKind::Static(Box::new(ty), mutability, Box::new(value)),
+ node: ItemStatic {
+ ty: Box::new(ty),
+ mutbl: mutability,
+ expr: Box::new(value),
+ }.into(),
})
));
@@ -428,7 +554,7 @@
ident: id,
vis: vis,
attrs: attrs,
- node: ItemKind::Const(Box::new(ty), Box::new(value)),
+ node: ItemConst { ty: Box::new(ty), expr: Box::new(value) }.into(),
})
));
@@ -458,23 +584,23 @@
attrs.extend(inner_attrs);
attrs
},
- node: ItemKind::Fn(
- Box::new(FnDecl {
+ node: ItemFn {
+ decl: Box::new(FnDecl {
inputs: inputs,
output: ret.map(FunctionRetTy::Ty).unwrap_or(FunctionRetTy::Default),
variadic: false,
}),
- unsafety,
- constness,
- abi,
- Generics {
+ unsafety: unsafety,
+ constness: constness,
+ abi: abi,
+ generics: Generics {
where_clause: where_clause,
.. generics
},
- Box::new(Block {
+ block: Box::new(Block {
stmts: stmts,
}),
- ),
+ }.into(),
})
));
@@ -485,21 +611,21 @@
mutability: mutability >>
keyword!("self") >>
not!(punct!(":")) >>
- (FnArg::SelfRef(lt, mutability))
+ (ArgSelfRef { lifetime: lt, mutbl: mutability }.into())
)
|
do_parse!(
mutability: mutability >>
keyword!("self") >>
not!(punct!(":")) >>
- (FnArg::SelfValue(mutability))
+ (ArgSelf { mutbl: mutability }.into())
)
|
do_parse!(
pat: pat >>
punct!(":") >>
ty: ty >>
- (FnArg::Captured(pat, ty))
+ (ArgCaptured { pat: pat, ty: ty }.into())
)
|
ty => { FnArg::Ignored }
@@ -531,13 +657,13 @@
attrs.extend(inner_attrs);
attrs
},
- node: ItemKind::Mod(Some(items)),
+ node: ItemMod { items: Some(items) }.into(),
},
None => Item {
ident: id,
vis: vis,
attrs: outer_attrs,
- node: ItemKind::Mod(None),
+ node: ItemMod { items: None }.into(),
},
})
));
@@ -552,10 +678,10 @@
ident: "".into(),
vis: Visibility::Inherited,
attrs: attrs,
- node: ItemKind::ForeignMod(ForeignMod {
+ node: ItemForeignMod {
abi: abi,
items: items,
- }),
+ }.into(),
})
));
@@ -582,17 +708,17 @@
(ForeignItem {
ident: name,
attrs: attrs,
- node: ForeignItemKind::Fn(
- Box::new(FnDecl {
+ node: ForeignItemFn {
+ decl: Box::new(FnDecl {
inputs: inputs,
output: ret.map(FunctionRetTy::Ty).unwrap_or(FunctionRetTy::Default),
variadic: variadic.is_some(),
}),
- Generics {
+ generics: Generics {
where_clause: where_clause,
.. generics
},
- ),
+ }.into(),
vis: vis,
})
));
@@ -609,7 +735,7 @@
(ForeignItem {
ident: id,
attrs: attrs,
- node: ForeignItemKind::Static(Box::new(ty), mutability),
+ node: ForeignItemStatic { ty: Box::new(ty), mutbl: mutability }.into(),
vis: vis,
})
));
@@ -628,13 +754,13 @@
ident: id,
vis: vis,
attrs: attrs,
- node: ItemKind::Ty(
- Box::new(ty),
- Generics {
+ node: ItemTy {
+ ty: Box::new(ty),
+ generics: Generics {
where_clause: where_clause,
..generics
},
- ),
+ }.into(),
})
));
@@ -646,10 +772,10 @@
attrs: def.attrs,
node: match def.body {
Body::Enum(variants) => {
- ItemKind::Enum(variants, def.generics)
+ ItemEnum { variants: variants, generics: def.generics }.into()
}
Body::Struct(variant_data) => {
- ItemKind::Struct(variant_data, def.generics)
+ ItemStruct { data: variant_data, generics: def.generics }.into()
}
}
}
@@ -667,13 +793,13 @@
ident: id,
vis: vis,
attrs: attrs,
- node: ItemKind::Union(
- VariantData::Struct(fields),
- Generics {
+ node: ItemUnion {
+ data: VariantData::Struct(fields),
+ generics: Generics {
where_clause: where_clause,
.. generics
},
- ),
+ }.into(),
})
));
@@ -696,15 +822,15 @@
ident: id,
vis: vis,
attrs: attrs,
- node: ItemKind::Trait(
- unsafety,
- Generics {
+ node: ItemTrait {
+ unsafety: unsafety,
+ generics: Generics {
where_clause: where_clause,
.. generics
},
- bounds,
- body,
- ),
+ supertraits: bounds,
+ items: body,
+ }.into(),
})
));
@@ -721,7 +847,7 @@
ident: "".into(),
vis: Visibility::Inherited,
attrs: attrs,
- node: ItemKind::DefaultImpl(unsafety, path),
+ node: ItemDefaultImpl { unsafety: unsafety, path: path }.into(),
})
));
@@ -746,7 +872,7 @@
(TraitItem {
ident: id,
attrs: attrs,
- node: TraitItemKind::Const(ty, value),
+ node: TraitItemConst { ty: ty, default: value }.into(),
})
));
@@ -781,8 +907,8 @@
attrs.extend(inner_attrs);
attrs
},
- node: TraitItemKind::Method(
- MethodSig {
+ node: TraitItemMethod {
+ sig: MethodSig {
unsafety: unsafety,
constness: constness,
abi: abi,
@@ -796,8 +922,8 @@
.. generics
},
},
- stmts.map(|stmts| Block { stmts: stmts }),
- ),
+ default: stmts.map(|stmts| Block { stmts: stmts }),
+ }.into(),
}
})
));
@@ -815,7 +941,7 @@
(TraitItem {
ident: id,
attrs: attrs,
- node: TraitItemKind::Type(bounds, default),
+ node: TraitItemType { bounds: bounds, default: default }.into(),
})
));
@@ -862,17 +988,17 @@
ident: "".into(),
vis: Visibility::Inherited,
attrs: attrs,
- node: ItemKind::Impl(
- unsafety,
- polarity_path.0,
- Generics {
+ node: ItemImpl {
+ unsafety: unsafety,
+ polarity: polarity_path.0,
+ generics: Generics {
where_clause: where_clause,
.. generics
},
- polarity_path.1,
- Box::new(self_ty),
- body,
- ),
+ trait_: polarity_path.1,
+ self_ty: Box::new(self_ty),
+ items: body,
+ }.into(),
})
));
@@ -902,7 +1028,7 @@
vis: vis,
defaultness: defaultness,
attrs: attrs,
- node: ImplItemKind::Const(ty, value),
+ node: ImplItemConst { ty: ty, expr: value}.into(),
})
));
@@ -934,8 +1060,8 @@
attrs.extend(inner_attrs);
attrs
},
- node: ImplItemKind::Method(
- MethodSig {
+ node: ImplItemMethod {
+ sig: MethodSig {
unsafety: unsafety,
constness: constness,
abi: abi,
@@ -949,10 +1075,10 @@
.. generics
},
},
- Block {
+ block: Block {
stmts: stmts,
},
- ),
+ }.into(),
})
));
@@ -970,7 +1096,7 @@
vis: vis,
defaultness: defaultness,
attrs: attrs,
- node: ImplItemKind::Type(ty),
+ node: ImplItemType { ty: ty }.into(),
})
));
@@ -1026,70 +1152,70 @@
fn to_tokens(&self, tokens: &mut Tokens) {
tokens.append_all(self.attrs.outer());
match self.node {
- ItemKind::ExternCrate(ref original) => {
+ ItemKind::ExternCrate(ref item) => {
self.vis.to_tokens(tokens);
tokens.append("extern");
tokens.append("crate");
- if let Some(ref original) = *original {
+ if let Some(ref original) = item.original {
original.to_tokens(tokens);
tokens.append("as");
}
self.ident.to_tokens(tokens);
tokens.append(";");
}
- ItemKind::Use(ref view_path) => {
+ ItemKind::Use(ref item) => {
self.vis.to_tokens(tokens);
tokens.append("use");
- view_path.to_tokens(tokens);
+ item.path.to_tokens(tokens);
tokens.append(";");
}
- ItemKind::Static(ref ty, ref mutability, ref expr) => {
+ ItemKind::Static(ref item) => {
self.vis.to_tokens(tokens);
tokens.append("static");
- mutability.to_tokens(tokens);
+ item.mutbl.to_tokens(tokens);
self.ident.to_tokens(tokens);
tokens.append(":");
- ty.to_tokens(tokens);
+ item.ty.to_tokens(tokens);
tokens.append("=");
- expr.to_tokens(tokens);
+ item.expr.to_tokens(tokens);
tokens.append(";");
}
- ItemKind::Const(ref ty, ref expr) => {
+ ItemKind::Const(ref item) => {
self.vis.to_tokens(tokens);
tokens.append("const");
self.ident.to_tokens(tokens);
tokens.append(":");
- ty.to_tokens(tokens);
+ item.ty.to_tokens(tokens);
tokens.append("=");
- expr.to_tokens(tokens);
+ item.expr.to_tokens(tokens);
tokens.append(";");
}
- ItemKind::Fn(ref decl, unsafety, constness, ref abi, ref generics, ref block) => {
+ ItemKind::Fn(ref item) => {
self.vis.to_tokens(tokens);
- constness.to_tokens(tokens);
- unsafety.to_tokens(tokens);
- abi.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);
- generics.to_tokens(tokens);
+ item.generics.to_tokens(tokens);
tokens.append("(");
- tokens.append_separated(&decl.inputs, ",");
+ tokens.append_separated(&item.decl.inputs, ",");
tokens.append(")");
- if let FunctionRetTy::Ty(ref ty) = decl.output {
+ if let FunctionRetTy::Ty(ref ty) = item.decl.output {
tokens.append("->");
ty.to_tokens(tokens);
}
- generics.where_clause.to_tokens(tokens);
+ item.generics.where_clause.to_tokens(tokens);
tokens.append("{");
tokens.append_all(self.attrs.inner());
- tokens.append_all(&block.stmts);
+ tokens.append_all(&item.block.stmts);
tokens.append("}");
}
- ItemKind::Mod(ref items) => {
+ ItemKind::Mod(ref item) => {
self.vis.to_tokens(tokens);
tokens.append("mod");
self.ident.to_tokens(tokens);
- match *items {
+ match item.items {
Some(ref items) => {
tokens.append("{");
tokens.append_all(self.attrs.inner());
@@ -1106,96 +1232,96 @@
tokens.append_all(&foreign_mod.items);
tokens.append("}");
}
- ItemKind::Ty(ref ty, ref generics) => {
+ ItemKind::Ty(ref item) => {
self.vis.to_tokens(tokens);
tokens.append("type");
self.ident.to_tokens(tokens);
- generics.to_tokens(tokens);
- generics.where_clause.to_tokens(tokens);
+ item.generics.to_tokens(tokens);
+ item.generics.where_clause.to_tokens(tokens);
tokens.append("=");
- ty.to_tokens(tokens);
+ item.ty.to_tokens(tokens);
tokens.append(";");
}
- ItemKind::Enum(ref variants, ref generics) => {
+ ItemKind::Enum(ref item) => {
self.vis.to_tokens(tokens);
tokens.append("enum");
self.ident.to_tokens(tokens);
- generics.to_tokens(tokens);
- generics.where_clause.to_tokens(tokens);
+ item.generics.to_tokens(tokens);
+ item.generics.where_clause.to_tokens(tokens);
tokens.append("{");
- for variant in variants {
+ for variant in &item.variants {
variant.to_tokens(tokens);
tokens.append(",");
}
tokens.append("}");
}
- ItemKind::Struct(ref variant_data, ref generics) => {
+ ItemKind::Struct(ref item) => {
self.vis.to_tokens(tokens);
tokens.append("struct");
self.ident.to_tokens(tokens);
- generics.to_tokens(tokens);
- match *variant_data {
+ item.generics.to_tokens(tokens);
+ match item.data {
VariantData::Struct(_) => {
- generics.where_clause.to_tokens(tokens);
- variant_data.to_tokens(tokens);
+ item.generics.where_clause.to_tokens(tokens);
+ item.data.to_tokens(tokens);
// no semicolon
}
VariantData::Tuple(_) => {
- variant_data.to_tokens(tokens);
- generics.where_clause.to_tokens(tokens);
+ item.data.to_tokens(tokens);
+ item.generics.where_clause.to_tokens(tokens);
tokens.append(";");
}
VariantData::Unit => {
- generics.where_clause.to_tokens(tokens);
+ item.generics.where_clause.to_tokens(tokens);
tokens.append(";");
}
}
}
- ItemKind::Union(ref variant_data, ref generics) => {
+ ItemKind::Union(ref item) => {
self.vis.to_tokens(tokens);
tokens.append("union");
self.ident.to_tokens(tokens);
- generics.to_tokens(tokens);
- generics.where_clause.to_tokens(tokens);
- variant_data.to_tokens(tokens);
+ item.generics.to_tokens(tokens);
+ item.generics.where_clause.to_tokens(tokens);
+ item.data.to_tokens(tokens);
}
- ItemKind::Trait(unsafety, ref generics, ref bound, ref items) => {
+ ItemKind::Trait(ref item) => {
self.vis.to_tokens(tokens);
- unsafety.to_tokens(tokens);
+ item.unsafety.to_tokens(tokens);
tokens.append("trait");
self.ident.to_tokens(tokens);
- generics.to_tokens(tokens);
- if !bound.is_empty() {
+ item.generics.to_tokens(tokens);
+ if !item.supertraits.is_empty() {
tokens.append(":");
- tokens.append_separated(bound, "+");
+ tokens.append_separated(&item.supertraits, "+");
}
- generics.where_clause.to_tokens(tokens);
+ item.generics.where_clause.to_tokens(tokens);
tokens.append("{");
- tokens.append_all(items);
+ tokens.append_all(&item.items);
tokens.append("}");
}
- ItemKind::DefaultImpl(unsafety, ref path) => {
- unsafety.to_tokens(tokens);
+ ItemKind::DefaultImpl(ref item) => {
+ item.unsafety.to_tokens(tokens);
tokens.append("impl");
- path.to_tokens(tokens);
+ item.path.to_tokens(tokens);
tokens.append("for");
tokens.append("..");
tokens.append("{");
tokens.append("}");
}
- ItemKind::Impl(unsafety, polarity, ref generics, ref path, ref ty, ref items) => {
- unsafety.to_tokens(tokens);
+ ItemKind::Impl(ref item) => {
+ item.unsafety.to_tokens(tokens);
tokens.append("impl");
- generics.to_tokens(tokens);
- if let Some(ref path) = *path {
- polarity.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");
}
- ty.to_tokens(tokens);
- generics.where_clause.to_tokens(tokens);
+ item.self_ty.to_tokens(tokens);
+ item.generics.where_clause.to_tokens(tokens);
tokens.append("{");
- tokens.append_all(items);
+ tokens.append_all(&item.items);
tokens.append("}");
}
ItemKind::Mac(ref mac) => {
@@ -1216,34 +1342,36 @@
}
}
- impl ToTokens for ViewPath {
+ impl ToTokens for PathSimple {
fn to_tokens(&self, tokens: &mut Tokens) {
- match *self {
- ViewPath::Simple(ref path, ref rename) => {
- path.to_tokens(tokens);
- if let Some(ref rename) = *rename {
- tokens.append("as");
- rename.to_tokens(tokens);
- }
- }
- ViewPath::Glob(ref path) => {
- path.to_tokens(tokens);
- tokens.append("::");
- tokens.append("*");
- }
- ViewPath::List(ref path, ref items) => {
- path.to_tokens(tokens);
- if path.global || !path.segments.is_empty() {
- tokens.append("::");
- }
- tokens.append("{");
- tokens.append_separated(items, ",");
- tokens.append("}");
- }
+ self.path.to_tokens(tokens);
+ if let Some(ref rename) = self.rename {
+ tokens.append("as");
+ rename.to_tokens(tokens);
}
}
}
+ impl ToTokens for PathGlob {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ self.path.to_tokens(tokens);
+ tokens.append("::");
+ tokens.append("*");
+ }
+ }
+
+ 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("}");
+ }
+ }
+
impl ToTokens for PathListItem {
fn to_tokens(&self, tokens: &mut Tokens) {
self.name.to_tokens(tokens);
@@ -1258,33 +1386,33 @@
fn to_tokens(&self, tokens: &mut Tokens) {
tokens.append_all(self.attrs.outer());
match self.node {
- TraitItemKind::Const(ref ty, ref expr) => {
+ TraitItemKind::Const(ref item) => {
tokens.append("const");
self.ident.to_tokens(tokens);
tokens.append(":");
- ty.to_tokens(tokens);
- if let Some(ref expr) = *expr {
+ item.ty.to_tokens(tokens);
+ if let Some(ref expr) = item.default {
tokens.append("=");
expr.to_tokens(tokens);
}
tokens.append(";");
}
- TraitItemKind::Method(ref sig, ref block) => {
- sig.constness.to_tokens(tokens);
- sig.unsafety.to_tokens(tokens);
- sig.abi.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);
- sig.generics.to_tokens(tokens);
+ item.sig.generics.to_tokens(tokens);
tokens.append("(");
- tokens.append_separated(&sig.decl.inputs, ",");
+ tokens.append_separated(&item.sig.decl.inputs, ",");
tokens.append(")");
- if let FunctionRetTy::Ty(ref ty) = sig.decl.output {
+ if let FunctionRetTy::Ty(ref ty) = item.sig.decl.output {
tokens.append("->");
ty.to_tokens(tokens);
}
- sig.generics.where_clause.to_tokens(tokens);
- match *block {
+ item.sig.generics.where_clause.to_tokens(tokens);
+ match item.default {
Some(ref block) => {
tokens.append("{");
tokens.append_all(self.attrs.inner());
@@ -1294,14 +1422,14 @@
None => tokens.append(";"),
}
}
- TraitItemKind::Type(ref bound, ref default) => {
+ TraitItemKind::Type(ref item) => {
tokens.append("type");
self.ident.to_tokens(tokens);
- if !bound.is_empty() {
+ if !item.bounds.is_empty() {
tokens.append(":");
- tokens.append_separated(bound, "+");
+ tokens.append_separated(&item.bounds, "+");
}
- if let Some(ref default) = *default {
+ if let Some(ref default) = item.default {
tokens.append("=");
default.to_tokens(tokens);
}
@@ -1324,46 +1452,46 @@
fn to_tokens(&self, tokens: &mut Tokens) {
tokens.append_all(self.attrs.outer());
match self.node {
- ImplItemKind::Const(ref ty, ref expr) => {
+ ImplItemKind::Const(ref item) => {
self.vis.to_tokens(tokens);
self.defaultness.to_tokens(tokens);
tokens.append("const");
self.ident.to_tokens(tokens);
tokens.append(":");
- ty.to_tokens(tokens);
+ item.ty.to_tokens(tokens);
tokens.append("=");
- expr.to_tokens(tokens);
+ item.expr.to_tokens(tokens);
tokens.append(";");
}
- ImplItemKind::Method(ref sig, ref block) => {
+ ImplItemKind::Method(ref item) => {
self.vis.to_tokens(tokens);
self.defaultness.to_tokens(tokens);
- sig.constness.to_tokens(tokens);
- sig.unsafety.to_tokens(tokens);
- sig.abi.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);
- sig.generics.to_tokens(tokens);
+ item.sig.generics.to_tokens(tokens);
tokens.append("(");
- tokens.append_separated(&sig.decl.inputs, ",");
+ tokens.append_separated(&item.sig.decl.inputs, ",");
tokens.append(")");
- if let FunctionRetTy::Ty(ref ty) = sig.decl.output {
+ if let FunctionRetTy::Ty(ref ty) = item.sig.decl.output {
tokens.append("->");
ty.to_tokens(tokens);
}
- sig.generics.where_clause.to_tokens(tokens);
+ item.sig.generics.where_clause.to_tokens(tokens);
tokens.append("{");
tokens.append_all(self.attrs.inner());
- tokens.append_all(&block.stmts);
+ tokens.append_all(&item.block.stmts);
tokens.append("}");
}
- ImplItemKind::Type(ref ty) => {
+ ImplItemKind::Type(ref item) => {
self.vis.to_tokens(tokens);
self.defaultness.to_tokens(tokens);
tokens.append("type");
self.ident.to_tokens(tokens);
tokens.append("=");
- ty.to_tokens(tokens);
+ item.ty.to_tokens(tokens);
tokens.append(";");
}
ImplItemKind::Macro(ref mac) => {
@@ -1383,62 +1511,61 @@
fn to_tokens(&self, tokens: &mut Tokens) {
tokens.append_all(self.attrs.outer());
match self.node {
- ForeignItemKind::Fn(ref decl, ref generics) => {
+ ForeignItemKind::Fn(ref item) => {
self.vis.to_tokens(tokens);
tokens.append("fn");
self.ident.to_tokens(tokens);
- generics.to_tokens(tokens);
+ item.generics.to_tokens(tokens);
tokens.append("(");
- tokens.append_separated(&decl.inputs, ",");
- if decl.variadic {
- if !decl.inputs.is_empty() {
+ 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) = decl.output {
+ if let FunctionRetTy::Ty(ref ty) = item.decl.output {
tokens.append("->");
ty.to_tokens(tokens);
}
- generics.where_clause.to_tokens(tokens);
+ item.generics.where_clause.to_tokens(tokens);
tokens.append(";");
}
- ForeignItemKind::Static(ref ty, mutability) => {
+ ForeignItemKind::Static(ref item) => {
self.vis.to_tokens(tokens);
tokens.append("static");
- mutability.to_tokens(tokens);
+ item.mutbl.to_tokens(tokens);
self.ident.to_tokens(tokens);
tokens.append(":");
- ty.to_tokens(tokens);
+ item.ty.to_tokens(tokens);
tokens.append(";");
}
}
}
}
- impl ToTokens for FnArg {
+ impl ToTokens for ArgSelfRef {
fn to_tokens(&self, tokens: &mut Tokens) {
- match *self {
- FnArg::SelfRef(ref lifetime, mutability) => {
- tokens.append("&");
- lifetime.to_tokens(tokens);
- mutability.to_tokens(tokens);
- tokens.append("self");
- }
- FnArg::SelfValue(mutability) => {
- mutability.to_tokens(tokens);
- tokens.append("self");
- }
- FnArg::Captured(ref pat, ref ty) => {
- pat.to_tokens(tokens);
- tokens.append(":");
- ty.to_tokens(tokens);
- }
- FnArg::Ignored(ref ty) => {
- ty.to_tokens(tokens);
- }
- }
+ tokens.append("&");
+ self.lifetime.to_tokens(tokens);
+ self.mutbl.to_tokens(tokens);
+ tokens.append("self");
+ }
+ }
+
+ impl ToTokens for ArgSelf {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ self.mutbl.to_tokens(tokens);
+ tokens.append("self");
+ }
+ }
+
+ impl ToTokens for ArgCaptured {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ self.pat.to_tokens(tokens);
+ tokens.append(":");
+ self.ty.to_tokens(tokens);
}
}
diff --git a/src/krate.rs b/src/krate.rs
index 077a36d..113e142 100644
--- a/src/krate.rs
+++ b/src/krate.rs
@@ -1,10 +1,11 @@
use super::*;
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-pub struct Crate {
- pub shebang: Option<String>,
- pub attrs: Vec<Attribute>,
- pub items: Vec<Item>,
+ast_struct! {
+ pub struct Crate {
+ pub shebang: Option<String>,
+ pub attrs: Vec<Attribute>,
+ pub items: Vec<Item>,
+ }
}
#[cfg(feature = "parsing")]
diff --git a/src/lib.rs b/src/lib.rs
index 3f7f0df..f30683f 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -15,11 +15,16 @@
#[cfg(feature = "aster")]
pub mod aster;
+#[macro_use]
+mod macros;
+
mod attr;
-pub use attr::{Attribute, AttrStyle, MetaItem, NestedMetaItem};
+pub use attr::{Attribute, AttrStyle, MetaItem, NestedMetaItem, MetaItemList,
+ MetaNameValue};
mod constant;
-pub use constant::ConstExpr;
+pub use constant::{ConstExpr, ConstCall, ConstBinary, ConstUnary, ConstCast,
+ ConstIndex, ConstParen};
mod data;
pub use data::{Field, Variant, VariantData, Visibility};
@@ -31,7 +36,13 @@
mod expr;
#[cfg(feature = "full")]
pub use expr::{Arm, BindingMode, Block, CaptureBy, Expr, ExprKind, FieldPat, FieldValue, Local,
- MacStmtStyle, Pat, RangeLimits, Stmt};
+ MacStmtStyle, Pat, RangeLimits, Stmt, ExprBox, ExprInPlace,
+ ExprArray, ExprCall, ExprMethodCall, ExprTup, ExprBinary, ExprUnary,
+ ExprCast, ExprType, ExprIf, ExprIfLet, ExprWhile, ExprWhileLet,
+ ExprForLoop, ExprLoop, ExprMatch, ExprClosure, ExprBlock,
+ ExprAssign, ExprAssignOp, ExprField, ExprTupField, ExprIndex,
+ ExprRange, ExprPath, ExprAddrOf, ExprBreak, ExprContinue,
+ ExprRet, ExprStruct, ExprRepeat, ExprParen, ExprTry, ExprCatch};
mod generics;
pub use generics::{Generics, Lifetime, LifetimeDef, TraitBoundModifier, TyParam, TyParamBound,
@@ -46,9 +57,15 @@
#[cfg(feature = "full")]
mod item;
#[cfg(feature = "full")]
-pub use item::{Constness, Defaultness, FnArg, FnDecl, ForeignItemKind, ForeignItem, ForeignMod,
+pub use item::{Constness, Defaultness, FnArg, FnDecl, ForeignItemKind, ForeignItem, ItemForeignMod,
ImplItem, ImplItemKind, ImplPolarity, Item, ItemKind, MethodSig, PathListItem,
- TraitItem, TraitItemKind, ViewPath};
+ TraitItem, TraitItemKind, ViewPath, ItemExternCrate, ItemUse,
+ ItemStatic, ItemConst, ItemFn, ItemMod, ItemTy, ItemEnum,
+ ItemStruct, ItemUnion, ItemTrait, ItemDefaultImpl, ItemImpl,
+ PathSimple, PathGlob, PathList, ForeignItemFn, ForeignItemStatic,
+ TraitItemConst, TraitItemMethod, TraitItemType,
+ ImplItemConst, ImplItemMethod, ImplItemType, ArgSelfRef,
+ ArgSelf, ArgCaptured};
#[cfg(feature = "full")]
mod krate;
@@ -75,7 +92,9 @@
mod ty;
pub use ty::{Abi, AngleBracketedParameterData, BareFnArg, BareFnTy, FunctionRetTy, MutTy,
Mutability, ParenthesizedParameterData, Path, PathParameters, PathSegment,
- PolyTraitRef, QSelf, Ty, TypeBinding, Unsafety};
+ PolyTraitRef, QSelf, Ty, TypeBinding, Unsafety, TySlice, TyArray,
+ TyPtr, TyRptr, TyBareFn, TyNever, TyTup, TyPath, TyTraitObject,
+ TyImplTrait, TyParen, TyInfer};
#[cfg(feature = "visit")]
pub mod visit;
diff --git a/src/lit.rs b/src/lit.rs
index 81be285..4811485 100644
--- a/src/lit.rs
+++ b/src/lit.rs
@@ -1,32 +1,34 @@
-/// Literal kind.
-///
-/// E.g. `"foo"`, `42`, `12.34` or `bool`
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-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),
+ast_enum! {
+ /// Literal kind.
+ ///
+ /// E.g. `"foo"`, `42`, `12.34` or `bool`
+ 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),
+ }
}
-#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
-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),
+ast_enum! {
+ 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 From<String> for Lit {
@@ -65,26 +67,30 @@
}
}
-#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
-pub enum IntTy {
- Isize,
- I8,
- I16,
- I32,
- I64,
- Usize,
- U8,
- U16,
- U32,
- U64,
- Unsuffixed,
+ast_enum! {
+ #[derive(Copy)]
+ pub enum IntTy {
+ Isize,
+ I8,
+ I16,
+ I32,
+ I64,
+ Usize,
+ U8,
+ U16,
+ U32,
+ U64,
+ Unsuffixed,
+ }
}
-#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
-pub enum FloatTy {
- F32,
- F64,
- Unsuffixed,
+ast_enum! {
+ #[derive(Copy)]
+ pub enum FloatTy {
+ F32,
+ F64,
+ Unsuffixed,
+ }
}
macro_rules! impl_from_for_lit {
diff --git a/src/mac.rs b/src/mac.rs
index 26b3c61..e6132e4 100644
--- a/src/mac.rs
+++ b/src/mac.rs
@@ -1,112 +1,120 @@
use super::*;
-/// Represents a macro invocation. The Path indicates which macro
-/// is being invoked, and the vector of token-trees contains the source
-/// of the macro invocation.
-///
-/// NB: the additional ident for a `macro_rules`-style macro is actually
-/// stored in the enclosing item. Oog.
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-pub struct Mac {
- pub path: Path,
- pub tts: Vec<TokenTree>,
+ast_struct! {
+ /// Represents a macro invocation. The Path indicates which macro
+ /// is being invoked, and the vector of token-trees contains the source
+ /// of the macro invocation.
+ ///
+ /// NB: the additional ident for a `macro_rules`-style macro is actually
+ /// stored in the enclosing item. Oog.
+ pub struct Mac {
+ pub path: Path,
+ pub tts: Vec<TokenTree>,
+ }
}
-/// 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.
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-pub enum TokenTree {
- /// A single token
- Token(Token),
- /// A delimited sequence of token trees
- Delimited(Delimited),
+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),
+ }
}
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-pub struct Delimited {
- /// The type of delimiter
- pub delim: DelimToken,
- /// The delimited sequence of token trees
- pub tts: Vec<TokenTree>,
+ast_struct! {
+ pub struct Delimited {
+ /// The type of delimiter
+ pub delim: DelimToken,
+ /// The delimited sequence of token trees
+ pub tts: Vec<TokenTree>,
+ }
}
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-pub enum Token {
- // Expression-operator symbols.
- Eq,
- Lt,
- Le,
- EqEq,
- Ne,
- Ge,
- Gt,
- AndAnd,
- OrOr,
- Not,
- Tilde,
- BinOp(BinOpToken),
- BinOpEq(BinOpToken),
+ast_enum! {
+ pub enum Token {
+ // Expression-operator symbols.
+ Eq,
+ Lt,
+ Le,
+ EqEq,
+ Ne,
+ Ge,
+ Gt,
+ AndAnd,
+ OrOr,
+ Not,
+ Tilde,
+ BinOp(BinOpToken),
+ BinOpEq(BinOpToken),
- // Structural symbols
- At,
- Dot,
- DotDot,
- DotDotDot,
- Comma,
- Semi,
- Colon,
- ModSep,
- RArrow,
- LArrow,
- FatArrow,
- Pound,
- Dollar,
- Question,
+ // Structural symbols
+ At,
+ Dot,
+ DotDot,
+ DotDotDot,
+ Comma,
+ Semi,
+ Colon,
+ ModSep,
+ RArrow,
+ LArrow,
+ FatArrow,
+ Pound,
+ Dollar,
+ Question,
- // Literals
- Literal(Lit),
+ // Literals
+ Literal(Lit),
- // Name components
- Ident(Ident),
- Underscore,
- Lifetime(Ident),
+ // Name components
+ Ident(Ident),
+ Underscore,
+ Lifetime(Ident),
- DocComment(String),
+ DocComment(String),
+ }
}
-#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
-pub enum BinOpToken {
- Plus,
- Minus,
- Star,
- Slash,
- Percent,
- Caret,
- And,
- Or,
- Shl,
- Shr,
+ast_enum! {
+ #[derive(Copy)]
+ pub enum BinOpToken {
+ Plus,
+ Minus,
+ Star,
+ Slash,
+ Percent,
+ Caret,
+ And,
+ Or,
+ Shl,
+ Shr,
+ }
}
-/// A delimiter token
-#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
-pub enum DelimToken {
- /// A round parenthesis: `(` or `)`
- Paren,
- /// A square bracket: `[` or `]`
- Bracket,
- /// A curly brace: `{` or `}`
- Brace,
+ast_enum! {
+ /// A delimiter token
+ #[derive(Copy)]
+ pub enum DelimToken {
+ /// A round parenthesis: `(` or `)`
+ Paren,
+ /// A square bracket: `[` or `]`
+ Bracket,
+ /// A curly brace: `{` or `}`
+ Brace,
+ }
}
#[cfg(feature = "parsing")]
diff --git a/src/macros.rs b/src/macros.rs
new file mode 100644
index 0000000..656fe90
--- /dev/null
+++ b/src/macros.rs
@@ -0,0 +1,101 @@
+macro_rules! ast_struct {
+ (
+ $(#[$attr:meta])*
+ pub struct $name:ident {
+ $(
+ $(#[$field_attr:meta])*
+ pub $field:ident: $ty:ty,
+ )*
+ }
+ ) => {
+ $(#[$attr])*
+ #[derive(Debug, Clone, Eq, PartialEq, Hash)]
+ pub struct $name {
+ $(
+ $(#[$field_attr])*
+ pub $field: $ty,
+ )*
+ }
+ }
+}
+
+macro_rules! ast_enum {
+ (
+ $(#[$enum_attr:meta])*
+ pub enum $name:ident { $($variants:tt)* }
+ ) => (
+ $(#[$enum_attr])*
+ #[derive(Debug, Clone, Eq, PartialEq, Hash)]
+ pub enum $name {
+ $($variants)*
+ }
+ )
+}
+
+macro_rules! ast_enum_of_structs {
+ (
+ $(#[$enum_attr:meta])*
+ pub enum $name:ident {
+ $(
+ $(#[$variant_attr:meta])*
+ pub $variant:ident($member:ident $($rest:tt)*),
+ )*
+ }
+
+ $($remaining:tt)*
+ ) => (
+ ast_enum! {
+ $(#[$enum_attr])*
+ pub enum $name {
+ $(
+ $(#[$variant_attr])*
+ $variant($member),
+ )*
+ }
+ }
+
+ $(
+ maybe_ast_struct! {
+ $(#[$variant_attr])*
+ pub struct $member $($rest)*
+ }
+
+ impl From<$member> for $name {
+ fn from(e: $member) -> $name {
+ $name::$variant(e)
+ }
+ }
+ )*
+
+ generate_to_tokens! {
+ $($remaining)*
+ enum $name { $($variant,)* }
+ }
+ )
+}
+
+macro_rules! generate_to_tokens {
+ (do_not_generate_to_tokens $($foo:tt)*) => ();
+
+ (enum $name:ident { $($variant:ident,)* }) => (
+ #[cfg(feature = "printing")]
+ impl ::quote::ToTokens for $name {
+ fn to_tokens(&self, tokens: &mut ::quote::Tokens) {
+ match *self {
+ $(
+ $name::$variant(ref e) => e.to_tokens(tokens),
+ )*
+ }
+ }
+ }
+ )
+}
+
+macro_rules! maybe_ast_struct {
+ (
+ $(#[$attr:meta])*
+ pub struct $name:ident
+ ) => ();
+
+ ($($rest:tt)*) => (ast_struct! { $($rest)* });
+}
diff --git a/src/op.rs b/src/op.rs
index d4b0bc7..cac1741 100644
--- a/src/op.rs
+++ b/src/op.rs
@@ -1,51 +1,55 @@
-#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
-pub enum BinOp {
- /// The `+` operator (addition)
- Add,
- /// The `-` operator (subtraction)
- Sub,
- /// The `*` operator (multiplication)
- Mul,
- /// The `/` operator (division)
- Div,
- /// The `%` operator (modulus)
- Rem,
- /// The `&&` operator (logical and)
- And,
- /// The `||` operator (logical or)
- Or,
- /// The `^` operator (bitwise xor)
- BitXor,
- /// The `&` operator (bitwise and)
- BitAnd,
- /// The `|` operator (bitwise or)
- BitOr,
- /// The `<<` operator (shift left)
- Shl,
- /// The `>>` operator (shift right)
- Shr,
- /// The `==` operator (equality)
- Eq,
- /// The `<` operator (less than)
- Lt,
- /// The `<=` operator (less than or equal to)
- Le,
- /// The `!=` operator (not equal to)
- Ne,
- /// The `>=` operator (greater than or equal to)
- Ge,
- /// The `>` operator (greater than)
- Gt,
+ast_enum! {
+ #[derive(Copy)]
+ pub enum BinOp {
+ /// The `+` operator (addition)
+ Add,
+ /// The `-` operator (subtraction)
+ Sub,
+ /// The `*` operator (multiplication)
+ Mul,
+ /// The `/` operator (division)
+ Div,
+ /// The `%` operator (modulus)
+ Rem,
+ /// The `&&` operator (logical and)
+ And,
+ /// The `||` operator (logical or)
+ Or,
+ /// The `^` operator (bitwise xor)
+ BitXor,
+ /// The `&` operator (bitwise and)
+ BitAnd,
+ /// The `|` operator (bitwise or)
+ BitOr,
+ /// The `<<` operator (shift left)
+ Shl,
+ /// The `>>` operator (shift right)
+ Shr,
+ /// The `==` operator (equality)
+ Eq,
+ /// The `<` operator (less than)
+ Lt,
+ /// The `<=` operator (less than or equal to)
+ Le,
+ /// The `!=` operator (not equal to)
+ Ne,
+ /// The `>=` operator (greater than or equal to)
+ Ge,
+ /// The `>` operator (greater than)
+ Gt,
+ }
}
-#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
-pub enum UnOp {
- /// The `*` operator for dereferencing
- Deref,
- /// The `!` operator for logical inversion
- Not,
- /// The `-` operator for negation
- Neg,
+ast_enum! {
+ #[derive(Copy)]
+ pub enum UnOp {
+ /// The `*` operator for dereferencing
+ Deref,
+ /// The `!` operator for logical inversion
+ Not,
+ /// The `-` operator for negation
+ Neg,
+ }
}
#[cfg(feature = "parsing")]
diff --git a/src/ty.rs b/src/ty.rs
index 7b7d3af..4fb3328 100644
--- a/src/ty.rs
+++ b/src/ty.rs
@@ -1,67 +1,95 @@
use super::*;
-/// The different kinds of types recognized by the compiler
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-pub enum Ty {
- /// A variable-length array (`[T]`)
- Slice(Box<Ty>),
- /// A fixed length array (`[T; n]`)
- Array(Box<Ty>, ConstExpr),
- /// A raw pointer (`*const T` or `*mut T`)
- Ptr(Box<MutTy>),
- /// A reference (`&'a T` or `&'a mut T`)
- Rptr(Option<Lifetime>, Box<MutTy>),
- /// A bare function (e.g. `fn(usize) -> bool`)
- BareFn(Box<BareFnTy>),
- /// The never type (`!`)
- Never,
- /// A tuple (`(A, B, C, D, ...)`)
- Tup(Vec<Ty>),
- /// A path (`module::module::...::Type`), optionally
- /// "qualified", e.g. `<Vec<T> as SomeTrait>::SomeType`.
+ast_enum_of_structs! {
+ /// The different kinds of types recognized by the compiler
+ pub enum Ty {
+ /// A variable-length array (`[T]`)
+ pub Slice(TySlice {
+ pub ty: Box<Ty>,
+ }),
+ /// A fixed length array (`[T; n]`)
+ pub Array(TyArray {
+ pub ty: Box<Ty>,
+ pub amt: ConstExpr,
+ }),
+ /// A raw pointer (`*const T` or `*mut T`)
+ pub Ptr(TyPtr {
+ pub ty: Box<MutTy>,
+ }),
+ /// A reference (`&'a T` or `&'a mut T`)
+ pub Rptr(TyRptr {
+ pub lifetime: Option<Lifetime>,
+ pub ty: Box<MutTy>,
+ }),
+ /// A bare function (e.g. `fn(usize) -> bool`)
+ pub BareFn(TyBareFn {
+ pub ty: Box<BareFnTy>,
+ }),
+ /// The never type (`!`)
+ pub Never(TyNever {}),
+ /// A tuple (`(A, B, C, D, ...)`)
+ pub Tup(TyTup {
+ pub tys: Vec<Ty>,
+ }),
+ /// A path (`module::module::...::Type`), optionally
+ /// "qualified", e.g. `<Vec<T> as SomeTrait>::SomeType`.
+ ///
+ /// Type parameters are stored in the Path itself
+ pub Path(TyPath {
+ pub qself: Option<QSelf>,
+ pub path: Path,
+ }),
+ /// A trait object type `Bound1 + Bound2 + Bound3`
+ /// where `Bound` is a trait or a lifetime.
+ pub TraitObject(TyTraitObject {
+ pub bounds: Vec<TyParamBound>,
+ }),
+ /// An `impl Bound1 + Bound2 + Bound3` type
+ /// where `Bound` is a trait or a lifetime.
+ pub ImplTrait(TyImplTrait {
+ pub bounds: Vec<TyParamBound>,
+ }),
+ /// No-op; kept solely so that we can pretty-print faithfully
+ pub Paren(TyParen {
+ 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 {}),
+ /// A macro in the type position.
+ pub Mac(Mac),
+ }
+}
+
+ast_struct! {
+ pub struct MutTy {
+ pub ty: Ty,
+ pub mutability: Mutability,
+ }
+}
+
+ast_enum! {
+ #[derive(Copy)]
+ pub enum Mutability {
+ Mutable,
+ Immutable,
+ }
+}
+
+ast_struct! {
+ /// A "Path" is essentially Rust's notion of a name.
///
- /// Type parameters are stored in the Path itself
- Path(Option<QSelf>, Path),
- /// A trait object type `Bound1 + Bound2 + Bound3`
- /// where `Bound` is a trait or a lifetime.
- TraitObject(Vec<TyParamBound>),
- /// An `impl Bound1 + Bound2 + Bound3` type
- /// where `Bound` is a trait or a lifetime.
- ImplTrait(Vec<TyParamBound>),
- /// No-op; kept solely so that we can pretty-print faithfully
- Paren(Box<Ty>),
- /// TyKind::Infer means the type should be inferred instead of it having been
- /// specified. This can appear anywhere in a type.
- Infer,
- /// A macro in the type position.
- Mac(Mac),
-}
-
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-pub struct MutTy {
- pub ty: Ty,
- pub mutability: Mutability,
-}
-
-#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
-pub enum Mutability {
- Mutable,
- Immutable,
-}
-
-/// A "Path" is essentially Rust's notion of a name.
-///
-/// It's represented as a sequence of identifiers,
-/// along with a bunch of supporting information.
-///
-/// E.g. `std::cmp::PartialEq`
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-pub struct Path {
- /// A `::foo` path, is relative to the crate root rather than current
- /// module (like paths in an import).
- pub global: bool,
- /// The segments in the path: the things separated by `::`.
- pub segments: Vec<PathSegment>,
+ /// It's represented as a sequence of identifiers,
+ /// along with a bunch of supporting information.
+ ///
+ /// E.g. `std::cmp::PartialEq`
+ pub struct Path {
+ /// A `::foo` path, is relative to the crate root rather than current
+ /// module (like paths in an import).
+ pub global: bool,
+ /// The segments in the path: the things separated by `::`.
+ pub segments: Vec<PathSegment>,
+ }
}
impl<T> From<T> for Path
@@ -75,19 +103,20 @@
}
}
-/// A segment of a path: an identifier, an optional lifetime, and a set of types.
-///
-/// E.g. `std`, `String` or `Box<T>`
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-pub struct PathSegment {
- /// The identifier portion of this path segment.
- pub ident: Ident,
- /// Type/lifetime parameters attached to this path. They come in
- /// two flavors: `Path<A,B,C>` and `Path(A,B) -> C`. Note that
- /// this is more than just simple syntactic sugar; the use of
- /// parens affects the region binding rules, so we preserve the
- /// distinction.
- pub parameters: PathParameters,
+ast_struct! {
+ /// A segment of a path: an identifier, an optional lifetime, and a set of types.
+ ///
+ /// E.g. `std`, `String` or `Box<T>`
+ pub struct PathSegment {
+ /// The identifier portion of this path segment.
+ pub ident: Ident,
+ /// Type/lifetime parameters attached to this path. They come in
+ /// two flavors: `Path<A,B,C>` and `Path(A,B) -> C`. Note that
+ /// this is more than just simple syntactic sugar; the use of
+ /// parens affects the region binding rules, so we preserve the
+ /// distinction.
+ pub parameters: PathParameters,
+ }
}
impl<T> From<T> for PathSegment
@@ -101,15 +130,16 @@
}
}
-/// Parameters of a path segment.
-///
-/// E.g. `<A, B>` as in `Foo<A, B>` or `(A, B)` as in `Foo(A, B)`
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-pub enum PathParameters {
- /// The `<'a, A, B, C>` in `foo::bar::baz::<'a, A, B, C>`
- AngleBracketed(AngleBracketedParameterData),
- /// The `(A, B)` and `C` in `Foo(A, B) -> C`
- Parenthesized(ParenthesizedParameterData),
+ast_enum! {
+ /// Parameters of a path segment.
+ ///
+ /// E.g. `<A, B>` as in `Foo<A, B>` or `(A, B)` as in `Foo(A, B)`
+ pub enum PathParameters {
+ /// The `<'a, A, B, C>` in `foo::bar::baz::<'a, A, B, C>`
+ AngleBracketed(AngleBracketedParameterData),
+ /// The `(A, B)` and `C` in `Foo(A, B) -> C`
+ Parenthesized(ParenthesizedParameterData),
+ }
}
impl PathParameters {
@@ -128,104 +158,118 @@
}
}
-/// A path like `Foo<'a, T>`
-#[derive(Debug, Clone, Eq, PartialEq, Default, Hash)]
-pub struct AngleBracketedParameterData {
- /// The lifetime parameters for this path segment.
- pub lifetimes: Vec<Lifetime>,
- /// The type parameters for this path segment, if present.
- pub types: Vec<Ty>,
- /// Bindings (equality constraints) on associated types, if present.
+ast_struct! {
+ /// A path like `Foo<'a, T>`
+ #[derive(Default)]
+ pub struct AngleBracketedParameterData {
+ /// The lifetime parameters for this path segment.
+ pub lifetimes: Vec<Lifetime>,
+ /// The type parameters for this path segment, if present.
+ pub types: Vec<Ty>,
+ /// Bindings (equality constraints) on associated types, if present.
+ ///
+ /// E.g., `Foo<A=Bar>`.
+ pub bindings: Vec<TypeBinding>,
+ }
+}
+
+ast_struct! {
+ /// Bind a type to an associated type: `A=Foo`.
+ pub struct TypeBinding {
+ pub ident: Ident,
+ pub ty: Ty,
+ }
+}
+
+
+ast_struct! {
+ /// A path like `Foo(A,B) -> C`
+ pub struct ParenthesizedParameterData {
+ /// `(A, B)`
+ pub inputs: Vec<Ty>,
+ /// `C`
+ pub output: Option<Ty>,
+ }
+}
+
+ast_struct! {
+ pub struct PolyTraitRef {
+ /// The `'a` in `<'a> Foo<&'a T>`
+ pub bound_lifetimes: Vec<LifetimeDef>,
+ /// The `Foo<&'a T>` in `<'a> Foo<&'a T>`
+ pub trait_ref: Path,
+ }
+}
+
+ast_struct! {
+ /// The explicit Self type in a "qualified path". The actual
+ /// path, including the trait and the associated item, is stored
+ /// separately. `position` represents the index of the associated
+ /// item qualified with this Self type.
///
- /// E.g., `Foo<A=Bar>`.
- pub bindings: Vec<TypeBinding>,
-}
-
-/// Bind a type to an associated type: `A=Foo`.
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-pub struct TypeBinding {
- pub ident: Ident,
- pub ty: Ty,
-}
-
-/// A path like `Foo(A,B) -> C`
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-pub struct ParenthesizedParameterData {
- /// `(A, B)`
- pub inputs: Vec<Ty>,
- /// `C`
- pub output: Option<Ty>,
-}
-
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-pub struct PolyTraitRef {
- /// The `'a` in `<'a> Foo<&'a T>`
- pub bound_lifetimes: Vec<LifetimeDef>,
- /// The `Foo<&'a T>` in `<'a> Foo<&'a T>`
- pub trait_ref: Path,
-}
-
-/// The explicit Self type in a "qualified path". The actual
-/// path, including the trait and the associated item, is stored
-/// separately. `position` represents the index of the associated
-/// item qualified with this Self type.
-///
-/// ```rust,ignore
-/// <Vec<T> as a::b::Trait>::AssociatedItem
-/// ^~~~~ ~~~~~~~~~~~~~~^
-/// ty position = 3
-///
-/// <Vec<T>>::AssociatedItem
-/// ^~~~~ ^
-/// ty position = 0
-/// ```
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-pub struct QSelf {
- pub ty: Box<Ty>,
- pub position: usize,
-}
-
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-pub struct BareFnTy {
- pub unsafety: Unsafety,
- pub abi: Option<Abi>,
- pub lifetimes: Vec<LifetimeDef>,
- pub inputs: Vec<BareFnArg>,
- pub output: FunctionRetTy,
- pub variadic: bool,
-}
-
-#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
-pub enum Unsafety {
- Unsafe,
- Normal,
-}
-
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-pub enum Abi {
- Named(String),
- Rust,
-}
-
-/// An argument in a function type.
-///
-/// E.g. `bar: usize` as in `fn foo(bar: usize)`
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-pub struct BareFnArg {
- pub name: Option<Ident>,
- pub ty: Ty,
-}
-
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-pub enum FunctionRetTy {
- /// Return type is not specified.
+ /// ```rust,ignore
+ /// <Vec<T> as a::b::Trait>::AssociatedItem
+ /// ^~~~~ ~~~~~~~~~~~~~~^
+ /// ty position = 3
///
- /// Functions default to `()` and
- /// closures default to inference. Span points to where return
- /// type would be inserted.
- Default,
- /// Everything else
- Ty(Ty),
+ /// <Vec<T>>::AssociatedItem
+ /// ^~~~~ ^
+ /// ty position = 0
+ /// ```
+ pub struct QSelf {
+ pub ty: Box<Ty>,
+ pub position: usize,
+ }
+}
+
+ast_struct! {
+ pub struct BareFnTy {
+ pub unsafety: Unsafety,
+ pub abi: Option<Abi>,
+ pub lifetimes: Vec<LifetimeDef>,
+ pub inputs: Vec<BareFnArg>,
+ pub output: FunctionRetTy,
+ pub variadic: bool,
+ }
+}
+
+ast_enum! {
+ #[derive(Copy)]
+ pub enum Unsafety {
+ Unsafe,
+ Normal,
+ }
+}
+
+ast_enum! {
+ pub enum Abi {
+ Named(String),
+ Rust,
+ }
+}
+
+ast_struct! {
+ /// An argument in a function type.
+ ///
+ /// E.g. `bar: usize` as in `fn foo(bar: usize)`
+ pub struct BareFnArg {
+ pub name: Option<Ident>,
+ pub ty: Ty,
+ }
+}
+
+
+ast_enum! {
+ pub enum FunctionRetTy {
+ /// Return type is not specified.
+ ///
+ /// Functions default to `()` and
+ /// closures default to inference. Span points to where return
+ /// type would be inserted.
+ Default,
+ /// Everything else
+ Ty(Ty),
+ }
}
#[cfg(feature = "parsing")]
@@ -276,7 +320,7 @@
punct!("[") >>
elem: ty >>
punct!("]") >>
- (Ty::Slice(Box::new(elem)))
+ (TySlice { ty: Box::new(elem) }.into())
));
named!(ty_array -> Ty, do_parse!(
@@ -285,7 +329,7 @@
punct!(";") >>
len: array_len >>
punct!("]") >>
- (Ty::Array(Box::new(elem), len))
+ (TyArray { ty: Box::new(elem), amt: len }.into())
));
#[cfg(not(feature = "full"))]
@@ -309,10 +353,12 @@
keyword!("mut") => { |_| Mutability::Mutable }
) >>
target: ty >>
- (Ty::Ptr(Box::new(MutTy {
- ty: target,
- mutability: mutability,
- })))
+ (TyPtr {
+ ty: Box::new(MutTy {
+ ty: target,
+ mutability: mutability,
+ }),
+ }.into())
));
named!(ty_rptr -> Ty, do_parse!(
@@ -320,10 +366,13 @@
life: option!(lifetime) >>
mutability: mutability >>
target: ty >>
- (Ty::Rptr(life, Box::new(MutTy {
- ty: target,
- mutability: mutability,
- })))
+ (TyRptr {
+ lifetime: life,
+ ty: Box::new(MutTy {
+ ty: target,
+ mutability: mutability,
+ }),
+ }.into())
));
named!(ty_bare_fn -> Ty, do_parse!(
@@ -346,26 +395,28 @@
punct!("->"),
ty
)) >>
- (Ty::BareFn(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(),
- })))
+ (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(),
+ }),
+ }.into())
));
- named!(ty_never -> Ty, map!(punct!("!"), |_| Ty::Never));
+ named!(ty_never -> Ty, map!(punct!("!"), |_| TyNever {}.into()));
named!(ty_tup -> Ty, do_parse!(
punct!("(") >>
elems: terminated_list!(punct!(","), ty) >>
punct!(")") >>
- (Ty::Tup(elems))
+ (TyTup { tys: elems }.into())
));
named!(ty_path -> Ty, do_parse!(
@@ -381,7 +432,7 @@
path.segments.last_mut().unwrap().parameters = parenthesized;
}
if bounds.is_empty() {
- Ty::Path(qself, path)
+ TyPath { qself: qself, path: path }.into()
} else {
let path = TyParamBound::Trait(
PolyTraitRef {
@@ -391,7 +442,7 @@
TraitBoundModifier::None,
);
let bounds = Some(path).into_iter().chain(bounds).collect();
- Ty::TraitObject(bounds)
+ TyTraitObject { bounds: bounds }.into()
}
})
));
@@ -447,20 +498,20 @@
named!(ty_poly_trait_ref -> Ty, map!(
separated_nonempty_list!(punct!("+"), ty_param_bound),
- Ty::TraitObject
+ |x| TyTraitObject { bounds: x }.into()
));
named!(ty_impl_trait -> Ty, do_parse!(
keyword!("impl") >>
elem: separated_nonempty_list!(punct!("+"), ty_param_bound) >>
- (Ty::ImplTrait(elem))
+ (TyImplTrait { bounds: elem }.into())
));
named!(ty_paren -> Ty, do_parse!(
punct!("(") >>
elem: ty >>
punct!(")") >>
- (Ty::Paren(Box::new(elem)))
+ (TyParen { ty: Box::new(elem) }.into())
));
named!(pub mutability -> Mutability, alt!(
@@ -604,90 +655,122 @@
use super::*;
use quote::{Tokens, ToTokens};
- impl ToTokens for Ty {
+ impl ToTokens for TySlice {
fn to_tokens(&self, tokens: &mut Tokens) {
- match *self {
- Ty::Slice(ref inner) => {
- tokens.append("[");
- inner.to_tokens(tokens);
- tokens.append("]");
- }
- Ty::Array(ref inner, ref len) => {
- tokens.append("[");
- inner.to_tokens(tokens);
- tokens.append(";");
- len.to_tokens(tokens);
- tokens.append("]");
- }
- Ty::Ptr(ref target) => {
- tokens.append("*");
- match target.mutability {
- Mutability::Mutable => tokens.append("mut"),
- Mutability::Immutable => tokens.append("const"),
- }
- target.ty.to_tokens(tokens);
- }
- Ty::Rptr(ref lifetime, ref target) => {
- tokens.append("&");
- lifetime.to_tokens(tokens);
- target.mutability.to_tokens(tokens);
- target.ty.to_tokens(tokens);
- }
- Ty::BareFn(ref func) => {
- func.to_tokens(tokens);
- }
- Ty::Never => {
- tokens.append("!");
- }
- Ty::Tup(ref elems) => {
- tokens.append("(");
- tokens.append_separated(elems, ",");
- if elems.len() == 1 {
- tokens.append(",");
- }
- tokens.append(")");
- }
- Ty::Path(None, ref path) => {
- path.to_tokens(tokens);
- }
- Ty::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);
- }
- }
- Ty::TraitObject(ref bounds) => {
- tokens.append_separated(bounds, "+");
- }
- Ty::ImplTrait(ref bounds) => {
- tokens.append("impl");
- tokens.append_separated(bounds, "+");
- }
- Ty::Paren(ref inner) => {
- tokens.append("(");
- inner.to_tokens(tokens);
- tokens.append(")");
- }
- Ty::Infer => {
- tokens.append("_");
- }
- Ty::Mac(ref mac) => mac.to_tokens(tokens),
+ tokens.append("[");
+ self.ty.to_tokens(tokens);
+ tokens.append("]");
+ }
+ }
+
+ 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("]");
+ }
+ }
+
+ 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.ty.ty.to_tokens(tokens);
+ }
+ }
+
+ impl ToTokens for TyRptr {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ tokens.append("&");
+ self.lifetime.to_tokens(tokens);
+ match self.ty.mutability {
+ Mutability::Mutable => tokens.append("mut"),
+ Mutability::Immutable => {}
+ }
+ self.ty.ty.to_tokens(tokens);
+ }
+ }
+
+ impl ToTokens for TyBareFn {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ self.ty.to_tokens(tokens)
+ }
+ }
+
+ impl ToTokens for TyNever {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ tokens.append("!");
+ }
+ }
+
+ 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(")");
+ }
+ }
+
+ impl ToTokens for TyPath {
+ 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);
+ }
+ }
+ }
+
+ impl ToTokens for TyTraitObject {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ tokens.append_separated(&self.bounds, "+");
+ }
+ }
+
+ impl ToTokens for TyImplTrait {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ tokens.append("impl");
+ tokens.append_separated(&self.bounds, "+");
+ }
+ }
+
+ impl ToTokens for TyParen {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ tokens.append("(");
+ self.ty.to_tokens(tokens);
+ tokens.append(")");
+ }
+ }
+
+ impl ToTokens for TyInfer {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ tokens.append("_");
}
}
diff --git a/src/visit.rs b/src/visit.rs
index b0a0057..c2b6d53 100644
--- a/src/visit.rs
+++ b/src/visit.rs
@@ -180,38 +180,40 @@
}
pub fn walk_ty<V: Visitor>(visitor: &mut V, ty: &Ty) {
+ use ty::*;
+
match *ty {
- Ty::Slice(ref inner) |
- Ty::Paren(ref inner) => visitor.visit_ty(inner),
- Ty::Ptr(ref mutable_type) => visitor.visit_ty(&mutable_type.ty),
- Ty::Rptr(ref opt_lifetime, ref mutable_type) => {
- walk_list!(visitor, visit_lifetime, opt_lifetime);
- visitor.visit_ty(&mutable_type.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(ref tuple_element_types) => {
- walk_list!(visitor, visit_ty, tuple_element_types);
+ Ty::Never(_) | Ty::Infer(_) => {}
+ Ty::Tup(TyTup { ref tys }) => {
+ walk_list!(visitor, visit_ty, tys);
}
- Ty::BareFn(ref bare_fn) => {
- walk_list!(visitor, visit_lifetime_def, &bare_fn.lifetimes);
- for argument in &bare_fn.inputs {
+ Ty::BareFn(TyBareFn { ref ty }) => {
+ walk_list!(visitor, visit_lifetime_def, &ty.lifetimes);
+ for argument in &ty.inputs {
walk_opt_ident(visitor, &argument.name);
visitor.visit_ty(&argument.ty)
}
- visitor.visit_fn_ret_ty(&bare_fn.output)
+ visitor.visit_fn_ret_ty(&ty.output)
}
- Ty::Path(ref maybe_qself, ref path) => {
- if let Some(ref qself) = *maybe_qself {
+ Ty::Path(TyPath { ref qself, ref path }) => {
+ if let Some(ref qself) = *qself {
visitor.visit_ty(&qself.ty);
}
visitor.visit_path(path);
}
- Ty::Array(ref inner, ref len) => {
- visitor.visit_ty(inner);
- visitor.visit_const_expr(len);
+ Ty::Array(TyArray { ref ty, ref amt }) => {
+ visitor.visit_ty(ty);
+ visitor.visit_const_expr(amt);
}
- Ty::TraitObject(ref bounds) |
- Ty::ImplTrait(ref bounds) => {
+ Ty::TraitObject(TyTraitObject { ref bounds }) |
+ Ty::ImplTrait(TyImplTrait { ref bounds }) => {
walk_list!(visitor, visit_ty_param_bound, bounds);
}
Ty::Mac(ref mac) => {
@@ -311,36 +313,37 @@
}
pub fn walk_const_expr<V: Visitor>(visitor: &mut V, len: &ConstExpr) {
+ use constant::*;
+ use constant::ConstExpr::*;
+
match *len {
- ConstExpr::Call(ref function, ref args) => {
- visitor.visit_const_expr(function);
+ Call(ConstCall { ref func, ref args }) => {
+ visitor.visit_const_expr(func);
walk_list!(visitor, visit_const_expr, args);
}
- ConstExpr::Binary(_op, ref left, ref right) => {
+ Binary(ConstBinary { ref left, ref right, .. }) => {
visitor.visit_const_expr(left);
visitor.visit_const_expr(right);
}
- ConstExpr::Unary(_op, ref v) => {
- visitor.visit_const_expr(v);
- }
- ConstExpr::Lit(ref lit) => {
+ Lit(ref lit) => {
visitor.visit_lit(lit);
}
- ConstExpr::Cast(ref expr, ref ty) => {
+ Cast(ConstCast { ref expr, ref ty }) => {
visitor.visit_const_expr(expr);
visitor.visit_ty(ty);
}
- ConstExpr::Path(ref path) => {
+ Path(ref path) => {
visitor.visit_path(path);
}
- ConstExpr::Index(ref expr, ref index) => {
+ Index(ConstIndex { ref expr, ref index }) => {
visitor.visit_const_expr(expr);
visitor.visit_const_expr(index);
}
- ConstExpr::Paren(ref expr) => {
+ Unary(ConstUnary { ref expr, .. }) |
+ Paren(ConstParen { ref expr }) => {
visitor.visit_const_expr(expr);
}
- ConstExpr::Other(ref other) => {
+ Other(ref other) => {
#[cfg(feature = "full")]
fn walk_other<V: Visitor>(visitor: &mut V, other: &Expr) {
visitor.visit_expr(other);
@@ -364,59 +367,72 @@
#[cfg(feature = "full")]
pub fn walk_item<V: Visitor>(visitor: &mut V, item: &Item) {
+ use item::*;
+
visitor.visit_ident(&item.ident);
walk_list!(visitor, visit_attribute, &item.attrs);
match item.node {
- ItemKind::ExternCrate(ref ident) => {
- walk_opt_ident(visitor, ident);
+ ItemKind::ExternCrate(ItemExternCrate { ref original }) => {
+ walk_opt_ident(visitor, original);
}
- ItemKind::Use(ref view_path) => {
- visitor.visit_view_path(view_path);
+ ItemKind::Use(ItemUse { ref path }) => {
+ visitor.visit_view_path(path);
}
- ItemKind::Static(ref ty, _, ref expr) |
- ItemKind::Const(ref ty, ref expr) => {
+ ItemKind::Static(ItemStatic { ref ty, ref expr, .. }) |
+ ItemKind::Const(ItemConst { ref ty, ref expr }) => {
visitor.visit_ty(ty);
visitor.visit_expr(expr);
}
- ItemKind::Fn(ref decl, _, _, _, ref generics, ref body) => {
+ ItemKind::Fn(ItemFn { ref decl, ref generics, ref block, .. }) => {
visitor.visit_fn_decl(decl);
visitor.visit_generics(generics);
- walk_list!(visitor, visit_stmt, &body.stmts);
+ walk_list!(visitor, visit_stmt, &block.stmts);
}
- ItemKind::Mod(ref maybe_items) => {
- if let Some(ref items) = *maybe_items {
+ ItemKind::Mod(ItemMod { ref items }) => {
+ if let Some(ref items) = *items {
walk_list!(visitor, visit_item, items);
}
}
- ItemKind::ForeignMod(ref foreign_mod) => {
- walk_list!(visitor, visit_foreign_item, &foreign_mod.items);
+ ItemKind::ForeignMod(ItemForeignMod { ref items, .. }) => {
+ walk_list!(visitor, visit_foreign_item, items);
}
- ItemKind::Ty(ref ty, ref generics) => {
+ ItemKind::Ty(ItemTy { ref ty, ref generics }) => {
visitor.visit_ty(ty);
visitor.visit_generics(generics);
}
- ItemKind::Enum(ref variant, ref generics) => {
- walk_list!(visitor, visit_variant, variant, generics);
+ ItemKind::Enum(ItemEnum { ref variants, ref generics }) => {
+ walk_list!(visitor, visit_variant, variants, generics);
}
- ItemKind::Struct(ref variant_data, ref generics) |
- ItemKind::Union(ref variant_data, ref generics) => {
- visitor.visit_variant_data(variant_data, &item.ident, 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(_, ref generics, ref bounds, ref trait_items) => {
+ ItemKind::Trait(ItemTrait {
+ ref generics,
+ ref supertraits,
+ ref items,
+ ..
+ }) => {
visitor.visit_generics(generics);
- walk_list!(visitor, visit_ty_param_bound, bounds);
- walk_list!(visitor, visit_trait_item, trait_items);
+ walk_list!(visitor, visit_ty_param_bound, supertraits);
+ walk_list!(visitor, visit_trait_item, items);
}
- ItemKind::DefaultImpl(_, ref path) => {
+ ItemKind::DefaultImpl(ItemDefaultImpl { ref path, .. }) => {
visitor.visit_path(path);
}
- ItemKind::Impl(_, _, ref generics, ref maybe_path, ref ty, ref impl_items) => {
+ ItemKind::Impl(ItemImpl {
+ ref generics,
+ ref trait_,
+ ref self_ty,
+ ref items,
+ ..
+ }) => {
visitor.visit_generics(generics);
- if let Some(ref path) = *maybe_path {
+ if let Some(ref path) = *trait_ {
visitor.visit_path(path);
}
- visitor.visit_ty(ty);
- walk_list!(visitor, visit_impl_item, impl_items);
+ visitor.visit_ty(self_ty);
+ walk_list!(visitor, visit_impl_item, items);
}
ItemKind::Mac(ref mac) => visitor.visit_mac(mac),
}
@@ -425,73 +441,68 @@
#[cfg(feature = "full")]
#[cfg_attr(feature = "cargo-clippy", allow(cyclomatic_complexity))]
pub fn walk_expr<V: Visitor>(visitor: &mut V, expr: &Expr) {
+ use expr::*;
+ use expr::ExprKind::*;
+
walk_list!(visitor, visit_attribute, &expr.attrs);
match expr.node {
- ExprKind::InPlace(ref place, ref value) => {
+ InPlace(ExprInPlace { ref place, ref value }) => {
visitor.visit_expr(place);
visitor.visit_expr(value);
}
- ExprKind::Call(ref callee, ref args) => {
- visitor.visit_expr(callee);
+ Call(ExprCall { ref func, ref args }) => {
+ visitor.visit_expr(func);
walk_list!(visitor, visit_expr, args);
}
- ExprKind::MethodCall(ref name, ref ty_args, ref args) => {
- visitor.visit_ident(name);
- walk_list!(visitor, visit_ty, ty_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);
}
- ExprKind::Array(ref exprs) |
- ExprKind::Tup(ref exprs) => {
+ Array(ExprArray { ref exprs }) |
+ Tup(ExprTup { args: ref exprs }) => {
walk_list!(visitor, visit_expr, exprs);
}
- ExprKind::Unary(_, ref operand) => {
- visitor.visit_expr(operand);
- }
- ExprKind::Lit(ref lit) => {
+ Lit(ref lit) => {
visitor.visit_lit(lit);
}
- ExprKind::Cast(ref expr, ref ty) |
- ExprKind::Type(ref expr, ref ty) => {
+ Cast(ExprCast { ref expr, ref ty }) |
+ Type(ExprType { ref expr, ref ty }) => {
visitor.visit_expr(expr);
visitor.visit_ty(ty);
}
- ExprKind::If(ref cond, ref cons, ref maybe_alt) => {
+ If(ExprIf { ref cond, ref if_true, ref if_false }) => {
visitor.visit_expr(cond);
- walk_list!(visitor, visit_stmt, &cons.stmts);
- if let Some(ref alt) = *maybe_alt {
+ walk_list!(visitor, visit_stmt, &if_true.stmts);
+ if let Some(ref alt) = *if_false {
visitor.visit_expr(alt);
}
}
- ExprKind::IfLet(ref pat, ref cond, ref cons, ref maybe_alt) => {
+ IfLet(ExprIfLet { ref pat, ref expr, ref if_true, ref if_false }) => {
visitor.visit_pat(pat);
- visitor.visit_expr(cond);
- walk_list!(visitor, visit_stmt, &cons.stmts);
- if let Some(ref alt) = *maybe_alt {
+ visitor.visit_expr(expr);
+ walk_list!(visitor, visit_stmt, &if_true.stmts);
+ if let Some(ref alt) = *if_false {
visitor.visit_expr(alt);
}
}
- ExprKind::While(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);
}
- ExprKind::WhileLet(ref pat, ref cond, ref body, ref label) => {
- visitor.visit_pat(pat);
- visitor.visit_expr(cond);
- walk_list!(visitor, visit_stmt, &body.stmts);
- walk_opt_ident(visitor, label);
- }
- ExprKind::ForLoop(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);
}
- ExprKind::Loop(ref body, ref label) => {
+ Loop(ExprLoop { ref body, ref label }) => {
walk_list!(visitor, visit_stmt, &body.stmts);
walk_opt_ident(visitor, label);
}
- ExprKind::Match(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 {
walk_list!(visitor, visit_attribute, attrs);
@@ -502,82 +513,79 @@
visitor.visit_expr(body);
}
}
- ExprKind::Catch(ref body) => {
- walk_list!(visitor, visit_stmt, &body.stmts);
- }
- ExprKind::Closure(_, ref decl, ref expr) => {
+ Closure(ExprClosure { ref decl, ref body, .. }) => {
visitor.visit_fn_decl(decl);
- visitor.visit_expr(expr);
+ visitor.visit_expr(body);
}
- ExprKind::Block(_, ref block) => {
+ Catch(ExprCatch { ref block }) |
+ Block(ExprBlock { ref block, .. }) => {
walk_list!(visitor, visit_stmt, &block.stmts);
}
- ExprKind::Binary(_, ref lhs, ref rhs) |
- ExprKind::Assign(ref lhs, ref rhs) |
- ExprKind::AssignOp(_, ref lhs, ref rhs) => {
- visitor.visit_expr(lhs);
- visitor.visit_expr(rhs);
+ Binary(ExprBinary { ref left, ref right, .. }) |
+ Assign(ExprAssign { ref left, ref right }) |
+ AssignOp(ExprAssignOp { ref left, ref right, .. }) => {
+ visitor.visit_expr(left);
+ visitor.visit_expr(right);
}
- ExprKind::Field(ref obj, ref field) => {
- visitor.visit_expr(obj);
+ Field(ExprField { ref expr, ref field }) => {
+ visitor.visit_expr(expr);
visitor.visit_ident(field);
}
- ExprKind::TupField(ref obj, _) => {
- visitor.visit_expr(obj);
+ Index(ExprIndex { ref expr, ref index }) => {
+ visitor.visit_expr(expr);
+ visitor.visit_expr(index);
}
- ExprKind::Index(ref obj, ref idx) => {
- visitor.visit_expr(obj);
- visitor.visit_expr(idx);
- }
- ExprKind::Range(ref maybe_start, ref maybe_end, _) => {
- if let Some(ref start) = *maybe_start {
+ Range(ExprRange { ref from, ref to, .. }) => {
+ if let Some(ref start) = *from {
visitor.visit_expr(start);
}
- if let Some(ref end) = *maybe_end {
+ if let Some(ref end) = *to {
visitor.visit_expr(end);
}
}
- ExprKind::Path(ref maybe_qself, ref path) => {
- if let Some(ref qself) = *maybe_qself {
+ Path(ExprPath { ref qself, ref path }) => {
+ if let Some(ref qself) = *qself {
visitor.visit_ty(&qself.ty);
}
visitor.visit_path(path);
}
- ExprKind::Break(ref maybe_label, ref maybe_expr) => {
- walk_opt_ident(visitor, maybe_label);
- if let Some(ref expr) = *maybe_expr {
+ Break(ExprBreak { ref label, ref expr }) => {
+ walk_opt_ident(visitor, label);
+ if let Some(ref expr) = *expr {
visitor.visit_expr(expr);
}
}
- ExprKind::Continue(ref maybe_label) => {
- walk_opt_ident(visitor, maybe_label);
+ Continue(ExprContinue { ref label }) => {
+ walk_opt_ident(visitor, label);
}
- ExprKind::Ret(ref maybe_expr) => {
- if let Some(ref expr) = *maybe_expr {
+ Ret(ExprRet { ref expr }) => {
+ if let Some(ref expr) = *expr {
visitor.visit_expr(expr);
}
}
- ExprKind::Mac(ref mac) => {
+ Mac(ref mac) => {
visitor.visit_mac(mac);
}
- ExprKind::Struct(ref path, ref fields, ref maybe_base) => {
+ Struct(ExprStruct { ref path, ref fields, ref rest }) => {
visitor.visit_path(path);
for &FieldValue { ref ident, ref expr, .. } in fields {
visitor.visit_ident(ident);
visitor.visit_expr(expr);
}
- if let Some(ref base) = *maybe_base {
+ if let Some(ref base) = *rest {
visitor.visit_expr(base);
}
}
- ExprKind::Repeat(ref value, ref times) => {
- visitor.visit_expr(value);
- visitor.visit_expr(times);
+ Repeat(ExprRepeat { ref expr, ref amt }) => {
+ visitor.visit_expr(expr);
+ visitor.visit_expr(amt);
}
- ExprKind::Box(ref expr) |
- ExprKind::AddrOf(_, ref expr) |
- ExprKind::Paren(ref expr) |
- ExprKind::Try(ref expr) => {
+ TupField(ExprTupField { ref expr, .. }) |
+ Unary(ExprUnary { ref expr, .. }) |
+ Box(ExprBox { ref expr }) |
+ AddrOf(ExprAddrOf { ref expr, .. }) |
+ Paren(ExprParen { ref expr }) |
+ Try(ExprTry { ref expr }) => {
visitor.visit_expr(expr);
}
}
@@ -585,14 +593,16 @@
#[cfg(feature = "full")]
pub fn walk_foreign_item<V: Visitor>(visitor: &mut V, foreign_item: &ForeignItem) {
+ use item::*;
+
visitor.visit_ident(&foreign_item.ident);
walk_list!(visitor, visit_attribute, &foreign_item.attrs);
match foreign_item.node {
- ForeignItemKind::Fn(ref decl, ref generics) => {
+ ForeignItemKind::Fn(ForeignItemFn { ref decl, ref generics }) => {
visitor.visit_fn_decl(decl);
visitor.visit_generics(generics);
}
- ForeignItemKind::Static(ref ty, _) => {
+ ForeignItemKind::Static(ForeignItemStatic { ref ty, .. }) => {
visitor.visit_ty(ty);
}
}
@@ -654,11 +664,13 @@
#[cfg(feature = "full")]
pub fn walk_fn_decl<V: Visitor>(visitor: &mut V, fn_decl: &FnDecl) {
+ use item::*;
+
for input in &fn_decl.inputs {
match *input {
- FnArg::SelfRef(_, _) |
+ FnArg::SelfRef(_) |
FnArg::SelfValue(_) => {}
- FnArg::Captured(ref pat, ref ty) => {
+ FnArg::Captured(ArgCaptured { ref pat, ref ty }) => {
visitor.visit_pat(pat);
visitor.visit_ty(ty);
}
@@ -672,24 +684,26 @@
#[cfg(feature = "full")]
pub fn walk_trait_item<V: Visitor>(visitor: &mut V, trait_item: &TraitItem) {
+ use item::*;
+
visitor.visit_ident(&trait_item.ident);
walk_list!(visitor, visit_attribute, &trait_item.attrs);
match trait_item.node {
- TraitItemKind::Const(ref ty, ref maybe_expr) => {
+ TraitItemKind::Const(TraitItemConst { ref ty, ref default }) => {
visitor.visit_ty(ty);
- if let Some(ref expr) = *maybe_expr {
+ if let Some(ref expr) = *default {
visitor.visit_expr(expr);
}
}
- TraitItemKind::Method(ref method_sig, ref maybe_block) => {
- visitor.visit_method_sig(method_sig);
- if let Some(ref block) = *maybe_block {
+ 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(ref bounds, ref maybe_ty) => {
+ TraitItemKind::Type(TraitItemType { ref bounds, ref default }) => {
walk_list!(visitor, visit_ty_param_bound, bounds);
- if let Some(ref ty) = *maybe_ty {
+ if let Some(ref ty) = *default {
visitor.visit_ty(ty);
}
}
@@ -701,18 +715,20 @@
#[cfg(feature = "full")]
pub fn walk_impl_item<V: Visitor>(visitor: &mut V, impl_item: &ImplItem) {
+ use item::*;
+
visitor.visit_ident(&impl_item.ident);
walk_list!(visitor, visit_attribute, &impl_item.attrs);
match impl_item.node {
- ImplItemKind::Const(ref ty, ref expr) => {
+ ImplItemKind::Const(ImplItemConst { ref ty, ref expr }) => {
visitor.visit_ty(ty);
visitor.visit_expr(expr);
}
- ImplItemKind::Method(ref method_sig, ref block) => {
- visitor.visit_method_sig(method_sig);
+ ImplItemKind::Method(ImplItemMethod { ref sig, ref block }) => {
+ visitor.visit_method_sig(sig);
walk_list!(visitor, visit_stmt, &block.stmts);
}
- ImplItemKind::Type(ref ty) => {
+ ImplItemKind::Type(ImplItemType { ref ty }) => {
visitor.visit_ty(ty);
}
ImplItemKind::Macro(ref mac) => {
@@ -762,15 +778,16 @@
#[cfg(feature = "full")]
pub fn walk_view_path<V: Visitor>(visitor: &mut V, view_path: &ViewPath) {
+ use item::*;
match *view_path {
- ViewPath::Simple(ref path, ref maybe_ident) => {
+ ViewPath::Simple(PathSimple { ref path, ref rename }) => {
visitor.visit_path(path);
- walk_opt_ident(visitor, maybe_ident);
+ walk_opt_ident(visitor, rename);
}
- ViewPath::Glob(ref path) => {
+ ViewPath::Glob(PathGlob { ref path }) => {
visitor.visit_path(path);
}
- ViewPath::List(ref path, ref items) => {
+ ViewPath::List(PathList { ref path, ref items }) => {
visitor.visit_path(path);
for &PathListItem { ref name, ref rename } in items {
visitor.visit_ident(name);