Move all #[derive] impls behind Cargo feature gates
This commit moves all #[derive] annotations behind Cargo feature gates to add
the ability to strip them all out entirely. The `Clone` and `Copy` impls
continue to be enabled by default as they tend to be mega useful but other
equality/hash/debug impls are all default behind the `extra-impls` gate.
This commit, on my computer, has the following timings:
| features | before | after
|-------------------------------|---------|------
| default | 3.67 | 2.96
| *none* | 1.78 | 0.49
| {printing, parsing} | 3.71 | 2.57
| default + {full} | 8.50 | 6.31
| {full} | 3.53 | 0.70
| {full, printing, parsing} | 8.10 | 5.29
Closes #143
diff --git a/.travis.yml b/.travis.yml
index e5ceaf4..5b33626 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -38,11 +38,14 @@
cargo build --features full &&
cargo build --features 'visit fold' &&
cargo build --features 'full visit fold' &&
+ cargo build --no-default-features --features 'full parsing printing' &&
+ cargo build --no-default-features --features 'visit fold parsing printing' &&
+ cargo build --no-default-features --features 'full visit fold parsing printing' &&
(cd synom && cargo test)
;;
test)
git submodule update --init &&
- cargo test --features 'full aster visit fold' --release
+ cargo test --all-features --release
;;
clippy)
cargo install clippy --debug --force || exit
diff --git a/Cargo.toml b/Cargo.toml
index b3d0b53..72b7498 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -10,13 +10,15 @@
include = ["Cargo.toml", "src/**/*.rs", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
[features]
-default = ["parsing", "printing"]
+default = ["parsing", "printing", "clone-impls"]
aster = []
full = []
parsing = ["unicode-xid", "synom"]
printing = ["quote"]
visit = []
fold = []
+clone-impls = []
+extra-traits = []
[dependencies]
quote = { version = "0.3.7", optional = true }
diff --git a/src/attr.rs b/src/attr.rs
index fecfd9a..f839ec4 100644
--- a/src/attr.rs
+++ b/src/attr.rs
@@ -133,7 +133,7 @@
/// 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)]
+ #[cfg_attr(feature = "clone-impls", derive(Copy))]
pub enum AttrStyle {
/// Attribute of the form `#![...]`.
Outer,
@@ -230,14 +230,20 @@
fn outer(self) -> Self::Ret {
fn is_outer(attr: &&Attribute) -> bool {
- attr.style == AttrStyle::Outer
+ match attr.style {
+ AttrStyle::Outer => true,
+ _ => false,
+ }
}
self.into_iter().filter(is_outer)
}
fn inner(self) -> Self::Ret {
fn is_inner(attr: &&Attribute) -> bool {
- attr.style == AttrStyle::Inner
+ match attr.style {
+ AttrStyle::Inner => true,
+ _ => false,
+ }
}
self.into_iter().filter(is_inner)
}
@@ -369,7 +375,7 @@
// If this was a sugared doc, emit it in its original form instead of `#[doc = "..."]`
match *self {
Attribute {
- style,
+ ref style,
path: Path { global: false, ref segments },
ref tts,
is_sugared_doc: true,
@@ -380,7 +386,7 @@
{
if let TokenTree::Token(Token::Eq) = self.tts[0] {
if let TokenTree::Token(Token::Literal(Lit::Str(ref value, StrStyle::Cooked))) = self.tts[1] {
- match style {
+ match *style {
AttrStyle::Inner if value.starts_with("//!") => {
tokens.append(&format!("{}\n", value));
return;
diff --git a/src/data.rs b/src/data.rs
index d01d9e5..3916b25 100644
--- a/src/data.rs
+++ b/src/data.rs
@@ -247,7 +247,6 @@
mod printing {
use super::*;
use quote::{Tokens, ToTokens};
- use ty::PathParameters;
impl ToTokens for Variant {
fn to_tokens(&self, tokens: &mut Tokens) {
@@ -312,7 +311,7 @@
if !path.global &&
path.segments.len() == 1 &&
(path.segments[0].ident == "self" || path.segments[0].ident == "super") &&
- path.segments[0].parameters == PathParameters::none() {
+ path.segments[0].parameters.is_empty() {
// Don't emit preceding `in` if path is `self` or `super`
} else {
diff --git a/src/expr.rs b/src/expr.rs
index 39ab6c7..05f195a 100644
--- a/src/expr.rs
+++ b/src/expr.rs
@@ -341,7 +341,7 @@
ast_enum! {
/// How a macro was invoked.
- #[derive(Copy)]
+ #[cfg_attr(feature = "clone-impls", derive(Copy))]
pub enum MacStmtStyle {
/// The macro statement had a trailing semicolon, e.g. `foo! { ... };`
/// `foo!(...);`, `foo![...];`
@@ -439,7 +439,7 @@
ast_enum! {
/// A capture clause
- #[derive(Copy)]
+ #[cfg_attr(feature = "clone-impls", derive(Copy))]
pub enum CaptureBy {
Value,
Ref,
@@ -448,7 +448,7 @@
ast_enum! {
/// Limit types of a range (inclusive or exclusive)
- #[derive(Copy)]
+ #[cfg_attr(feature = "clone-impls", derive(Copy))]
pub enum RangeLimits {
/// Inclusive at the beginning, exclusive at the end
HalfOpen,
@@ -474,7 +474,7 @@
}
ast_enum! {
- #[derive(Copy)]
+ #[cfg_attr(feature = "clone-impls", derive(Copy))]
pub enum BindingMode {
ByRef(Mutability),
ByValue(Mutability),
@@ -1823,7 +1823,7 @@
fn to_tokens(&self, tokens: &mut Tokens) {
match *self {
Pat::Wild => tokens.append("_"),
- Pat::Ident(mode, ref ident, ref subpat) => {
+ Pat::Ident(ref mode, ref ident, ref subpat) => {
mode.to_tokens(tokens);
ident.to_tokens(tokens);
if let Some(ref subpat) = *subpat {
@@ -1911,7 +1911,7 @@
tokens.append("box");
inner.to_tokens(tokens);
}
- Pat::Ref(ref target, mutability) => {
+ Pat::Ref(ref target, ref mutability) => {
tokens.append("&");
mutability.to_tokens(tokens);
target.to_tokens(tokens);
@@ -1929,8 +1929,9 @@
if !before.is_empty() {
tokens.append(",");
}
- if **rest != Pat::Wild {
- rest.to_tokens(tokens);
+ match **rest {
+ Pat::Wild => {}
+ _ => rest.to_tokens(tokens),
}
tokens.append("..");
if !after.is_empty() {
@@ -2012,10 +2013,10 @@
tokens.append(";");
}
Stmt::Mac(ref mac) => {
- let (ref mac, style, ref attrs) = **mac;
+ let (ref mac, ref style, ref attrs) = **mac;
tokens.append_all(attrs.outer());
mac.to_tokens(tokens);
- match style {
+ match *style {
MacStmtStyle::Semicolon => tokens.append(";"),
MacStmtStyle::Braces | MacStmtStyle::NoBraces => {
// no semicolon
diff --git a/src/generics.rs b/src/generics.rs
index 2841a47..adf6dfa 100644
--- a/src/generics.rs
+++ b/src/generics.rs
@@ -12,19 +12,22 @@
}
#[cfg(feature = "printing")]
-/// Returned by `Generics::split_for_impl`.
-#[derive(Debug)]
-pub struct ImplGenerics<'a>(&'a Generics);
+ast_struct! {
+ /// Returned by `Generics::split_for_impl`.
+ pub struct ImplGenerics<'a>(&'a Generics);
+}
#[cfg(feature = "printing")]
-/// Returned by `Generics::split_for_impl`.
-#[derive(Debug)]
-pub struct TyGenerics<'a>(&'a Generics);
+ast_struct! {
+ /// Returned by `Generics::split_for_impl`.
+ pub struct TyGenerics<'a>(&'a Generics);
+}
#[cfg(feature = "printing")]
-/// Returned by `TyGenerics::as_turbofish`.
-#[derive(Debug)]
-pub struct Turbofish<'a>(&'a Generics);
+ast_struct! {
+ /// Returned by `TyGenerics::as_turbofish`.
+ pub struct Turbofish<'a>(&'a Generics);
+}
#[cfg(feature = "printing")]
impl Generics {
@@ -132,7 +135,7 @@
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)]
+ #[cfg_attr(feature = "clone-impls", derive(Copy))]
pub enum TraitBoundModifier {
None,
Maybe,
diff --git a/src/item.rs b/src/item.rs
index 7b25f2f..611e52a 100644
--- a/src/item.rs
+++ b/src/item.rs
@@ -184,7 +184,7 @@
}
ast_enum! {
- #[derive(Copy)]
+ #[cfg_attr(feature = "clone-impls", derive(Copy))]
pub enum Constness {
Const,
NotConst,
@@ -192,7 +192,7 @@
}
ast_enum! {
- #[derive(Copy)]
+ #[cfg_attr(feature = "clone-impls", derive(Copy))]
pub enum Defaultness {
Default,
Final,
@@ -269,7 +269,7 @@
}
ast_enum! {
- #[derive(Copy)]
+ #[cfg_attr(feature = "clone-impls", derive(Copy))]
pub enum ImplPolarity {
/// `impl Trait for Type`
Positive,
diff --git a/src/lit.rs b/src/lit.rs
index 4811485..72a2f43 100644
--- a/src/lit.rs
+++ b/src/lit.rs
@@ -2,6 +2,7 @@
/// Literal kind.
///
/// E.g. `"foo"`, `42`, `12.34` or `bool`
+ #[cfg_attr(not(feature = "clone-impls"), derive(Clone))]
pub enum Lit {
/// A string literal (`"foo"`)
Str(String, StrStyle),
@@ -21,6 +22,7 @@
}
ast_enum! {
+ #[cfg_attr(not(feature = "clone-impls"), derive(Clone))]
pub enum StrStyle {
/// A regular string, like `"foo"`
Cooked,
@@ -69,6 +71,7 @@
ast_enum! {
#[derive(Copy)]
+ #[cfg_attr(not(feature = "clone-impls"), derive(Clone))]
pub enum IntTy {
Isize,
I8,
@@ -86,6 +89,7 @@
ast_enum! {
#[derive(Copy)]
+ #[cfg_attr(not(feature = "clone-impls"), derive(Clone))]
pub enum FloatTy {
F32,
F64,
@@ -133,31 +137,35 @@
]}
#[cfg(feature = "parsing")]
-#[derive(Debug, Clone)]
-pub struct StrLit {
- pub value: String,
- pub style: StrStyle,
+ast_struct! {
+ pub struct StrLit {
+ pub value: String,
+ pub style: StrStyle,
+ }
}
#[cfg(feature = "parsing")]
-#[derive(Debug, Clone)]
-pub struct ByteStrLit {
- pub value: Vec<u8>,
- pub style: StrStyle,
+ast_struct! {
+ pub struct ByteStrLit {
+ pub value: Vec<u8>,
+ pub style: StrStyle,
+ }
}
#[cfg(feature = "parsing")]
-#[derive(Debug, Clone)]
-pub struct IntLit {
- pub value: u64,
- pub suffix: IntTy,
+ast_struct! {
+ pub struct IntLit {
+ pub value: u64,
+ pub suffix: IntTy,
+ }
}
#[cfg(feature = "parsing")]
-#[derive(Debug, Clone)]
-pub struct FloatLit {
- pub value: String,
- pub suffix: FloatTy,
+ast_struct! {
+ pub struct FloatLit {
+ pub value: String,
+ pub suffix: FloatTy,
+ }
}
#[cfg(feature = "parsing")]
diff --git a/src/mac.rs b/src/mac.rs
index e6132e4..dbed4eb 100644
--- a/src/mac.rs
+++ b/src/mac.rs
@@ -89,7 +89,7 @@
}
ast_enum! {
- #[derive(Copy)]
+ #[cfg_attr(feature = "clone-impls", derive(Copy))]
pub enum BinOpToken {
Plus,
Minus,
@@ -106,7 +106,7 @@
ast_enum! {
/// A delimiter token
- #[derive(Copy)]
+ #[cfg_attr(feature = "clone-impls", derive(Copy))]
pub enum DelimToken {
/// A round parenthesis: `(` or `)`
Paren,
@@ -371,8 +371,8 @@
Token::OrOr => tokens.append("||"),
Token::Not => tokens.append("!"),
Token::Tilde => tokens.append("~"),
- Token::BinOp(binop) => tokens.append(binop.op()),
- Token::BinOpEq(binop) => tokens.append(binop.assign_op()),
+ Token::BinOp(ref binop) => tokens.append(binop.op()),
+ Token::BinOpEq(ref binop) => tokens.append(binop.assign_op()),
Token::At => tokens.append("@"),
Token::Dot => tokens.append("."),
Token::DotDot => tokens.append(".."),
diff --git a/src/macros.rs b/src/macros.rs
index 656fe90..bd686ac 100644
--- a/src/macros.rs
+++ b/src/macros.rs
@@ -1,21 +1,12 @@
macro_rules! ast_struct {
(
$(#[$attr:meta])*
- pub struct $name:ident {
- $(
- $(#[$field_attr:meta])*
- pub $field:ident: $ty:ty,
- )*
- }
+ pub struct $name:ident $($rest:tt)*
) => {
$(#[$attr])*
- #[derive(Debug, Clone, Eq, PartialEq, Hash)]
- pub struct $name {
- $(
- $(#[$field_attr])*
- pub $field: $ty,
- )*
- }
+ #[cfg_attr(feature = "extra-traits", derive(Debug, Eq, PartialEq, Hash))]
+ #[cfg_attr(feature = "clone-impls", derive(Clone))]
+ pub struct $name $($rest)*
}
}
@@ -25,7 +16,8 @@
pub enum $name:ident { $($variants:tt)* }
) => (
$(#[$enum_attr])*
- #[derive(Debug, Clone, Eq, PartialEq, Hash)]
+ #[cfg_attr(feature = "extra-traits", derive(Debug, Eq, PartialEq, Hash))]
+ #[cfg_attr(feature = "clone-impls", derive(Clone))]
pub enum $name {
$($variants)*
}
diff --git a/src/op.rs b/src/op.rs
index cac1741..6393e00 100644
--- a/src/op.rs
+++ b/src/op.rs
@@ -1,5 +1,5 @@
ast_enum! {
- #[derive(Copy)]
+ #[cfg_attr(feature = "clone-impls", derive(Copy))]
pub enum BinOp {
/// The `+` operator (addition)
Add,
@@ -41,7 +41,7 @@
}
ast_enum! {
- #[derive(Copy)]
+ #[cfg_attr(feature = "clone-impls", derive(Copy))]
pub enum UnOp {
/// The `*` operator for dereferencing
Deref,
diff --git a/src/ty.rs b/src/ty.rs
index 4fb3328..7345da7 100644
--- a/src/ty.rs
+++ b/src/ty.rs
@@ -69,7 +69,7 @@
}
ast_enum! {
- #[derive(Copy)]
+ #[cfg_attr(feature = "clone-impls", derive(Copy))]
pub enum Mutability {
Mutable,
Immutable,
@@ -234,7 +234,7 @@
}
ast_enum! {
- #[derive(Copy)]
+ #[cfg_attr(feature = "clone-impls", derive(Copy))]
pub enum Unsafety {
Unsafe,
Normal,
@@ -422,7 +422,7 @@
named!(ty_path -> Ty, do_parse!(
qpath: qpath >>
parenthesized: cond!(
- qpath.1.segments.last().unwrap().parameters == PathParameters::none(),
+ qpath.1.segments.last().unwrap().parameters.is_empty(),
option!(parenthesized_parameter_data)
) >>
bounds: many0!(preceded!(punct!("+"), ty_param_bound)) >>
@@ -605,7 +605,7 @@
bound_lifetimes: bound_lifetimes >>
trait_ref: path >>
parenthesized: option!(cond_reduce!(
- trait_ref.segments.last().unwrap().parameters == PathParameters::none(),
+ trait_ref.segments.last().unwrap().parameters.is_empty(),
parenthesized_parameter_data
)) >>
({
diff --git a/synom/Cargo.toml b/synom/Cargo.toml
index fde5ed4..988c5bc 100644
--- a/synom/Cargo.toml
+++ b/synom/Cargo.toml
@@ -16,5 +16,5 @@
[dev-dependencies.syn]
version = "0.11"
path = ".."
-features = ["parsing", "full"]
+features = ["parsing", "full", "extra-traits"]
default-features = false
diff --git a/tests/test_generics.rs b/tests/test_generics.rs
index 08886bb..92ae9e9 100644
--- a/tests/test_generics.rs
+++ b/tests/test_generics.rs
@@ -1,3 +1,5 @@
+#![cfg(feature = "extra-traits")]
+
extern crate syn;
use syn::*;
diff --git a/tests/test_macro_input.rs b/tests/test_macro_input.rs
index 4e6bbd8..653fbe2 100644
--- a/tests/test_macro_input.rs
+++ b/tests/test_macro_input.rs
@@ -2,6 +2,7 @@
//!
//! Deprecation warnings are suppressed to keep the output clean.
#![allow(deprecated)]
+#![cfg(feature = "extra-traits")]
extern crate syn;
use syn::*;
diff --git a/tests/test_meta_item.rs b/tests/test_meta_item.rs
index 735c9a2..72cec3a 100644
--- a/tests/test_meta_item.rs
+++ b/tests/test_meta_item.rs
@@ -1,3 +1,5 @@
+#![cfg(feature = "extra-traits")]
+
extern crate syn;
use syn::*;
diff --git a/tests/test_token_trees.rs b/tests/test_token_trees.rs
index 8351f54..33dbdda 100644
--- a/tests/test_token_trees.rs
+++ b/tests/test_token_trees.rs
@@ -1,3 +1,5 @@
+#![cfg(feature = "extra-traits")]
+
extern crate syn;
use syn::TokenTree::{self, Token};
use syn::DelimToken::*;