mirror of
https://github.com/pezkuwichain/serde.git
synced 2026-06-15 20:11:01 +00:00
Remove dependency on syn/visit feature
The builtin visitor is fairly expensive to compile (3700 lines of code), particularly if something else in the dependency graph also enables syn/full. For the usage in serde_derive, it turns out to be easy to replace.
This commit is contained in:
@@ -22,7 +22,7 @@ proc-macro = true
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
proc-macro2 = "1.0"
|
proc-macro2 = "1.0"
|
||||||
quote = "1.0"
|
quote = "1.0"
|
||||||
syn = { version = "1.0.58", features = ["visit"] }
|
syn = "1.0.60"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
serde = { version = "1.0", path = "../serde" }
|
serde = { version = "1.0", path = "../serde" }
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ use std::collections::HashSet;
|
|||||||
|
|
||||||
use syn;
|
use syn;
|
||||||
use syn::punctuated::{Pair, Punctuated};
|
use syn::punctuated::{Pair, Punctuated};
|
||||||
use syn::visit::{self, Visit};
|
|
||||||
|
|
||||||
use internals::ast::{Container, Data};
|
use internals::ast::{Container, Data};
|
||||||
use internals::{attr, ungroup};
|
use internals::{attr, ungroup};
|
||||||
@@ -112,7 +111,8 @@ pub fn with_bound(
|
|||||||
// parameters.
|
// parameters.
|
||||||
associated_type_usage: Vec<&'ast syn::TypePath>,
|
associated_type_usage: Vec<&'ast syn::TypePath>,
|
||||||
}
|
}
|
||||||
impl<'ast> Visit<'ast> for FindTyParams<'ast> {
|
|
||||||
|
impl<'ast> FindTyParams<'ast> {
|
||||||
fn visit_field(&mut self, field: &'ast syn::Field) {
|
fn visit_field(&mut self, field: &'ast syn::Field) {
|
||||||
if let syn::Type::Path(ty) = ungroup(&field.ty) {
|
if let syn::Type::Path(ty) = ungroup(&field.ty) {
|
||||||
if let Some(Pair::Punctuated(t, _)) = ty.path.segments.pairs().next() {
|
if let Some(Pair::Punctuated(t, _)) = ty.path.segments.pairs().next() {
|
||||||
@@ -138,7 +138,98 @@ pub fn with_bound(
|
|||||||
self.relevant_type_params.insert(id.clone());
|
self.relevant_type_params.insert(id.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
visit::visit_path(self, path);
|
for segment in &path.segments {
|
||||||
|
self.visit_path_segment(segment);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Everything below is simply traversing the syntax tree.
|
||||||
|
|
||||||
|
fn visit_type(&mut self, ty: &'ast syn::Type) {
|
||||||
|
match ty {
|
||||||
|
syn::Type::Array(ty) => self.visit_type(&ty.elem),
|
||||||
|
syn::Type::BareFn(ty) => {
|
||||||
|
for arg in &ty.inputs {
|
||||||
|
self.visit_type(&arg.ty);
|
||||||
|
}
|
||||||
|
self.visit_return_type(&ty.output);
|
||||||
|
}
|
||||||
|
syn::Type::Group(ty) => self.visit_type(&ty.elem),
|
||||||
|
syn::Type::ImplTrait(ty) => {
|
||||||
|
for bound in &ty.bounds {
|
||||||
|
self.visit_type_param_bound(bound);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
syn::Type::Macro(ty) => self.visit_macro(&ty.mac),
|
||||||
|
syn::Type::Paren(ty) => self.visit_type(&ty.elem),
|
||||||
|
syn::Type::Path(ty) => {
|
||||||
|
if let Some(qself) = &ty.qself {
|
||||||
|
self.visit_type(&qself.ty);
|
||||||
|
}
|
||||||
|
self.visit_path(&ty.path);
|
||||||
|
}
|
||||||
|
syn::Type::Ptr(ty) => self.visit_type(&ty.elem),
|
||||||
|
syn::Type::Reference(ty) => self.visit_type(&ty.elem),
|
||||||
|
syn::Type::Slice(ty) => self.visit_type(&ty.elem),
|
||||||
|
syn::Type::TraitObject(ty) => {
|
||||||
|
for bound in &ty.bounds {
|
||||||
|
self.visit_type_param_bound(bound);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
syn::Type::Tuple(ty) => {
|
||||||
|
for elem in &ty.elems {
|
||||||
|
self.visit_type(elem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
syn::Type::Infer(_) | syn::Type::Never(_) | syn::Type::Verbatim(_) => {}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
syn::Type::__TestExhaustive(_) => unimplemented!(),
|
||||||
|
#[cfg(not(test))]
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_path_segment(&mut self, segment: &'ast syn::PathSegment) {
|
||||||
|
self.visit_path_arguments(&segment.arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_path_arguments(&mut self, arguments: &'ast syn::PathArguments) {
|
||||||
|
match arguments {
|
||||||
|
syn::PathArguments::None => {}
|
||||||
|
syn::PathArguments::AngleBracketed(arguments) => {
|
||||||
|
for arg in &arguments.args {
|
||||||
|
match arg {
|
||||||
|
syn::GenericArgument::Type(arg) => self.visit_type(arg),
|
||||||
|
syn::GenericArgument::Binding(arg) => self.visit_type(&arg.ty),
|
||||||
|
syn::GenericArgument::Lifetime(_)
|
||||||
|
| syn::GenericArgument::Constraint(_)
|
||||||
|
| syn::GenericArgument::Const(_) => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
syn::PathArguments::Parenthesized(arguments) => {
|
||||||
|
for argument in &arguments.inputs {
|
||||||
|
self.visit_type(argument);
|
||||||
|
}
|
||||||
|
self.visit_return_type(&arguments.output);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_return_type(&mut self, return_type: &'ast syn::ReturnType) {
|
||||||
|
match return_type {
|
||||||
|
syn::ReturnType::Default => {}
|
||||||
|
syn::ReturnType::Type(_, output) => self.visit_type(output),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_type_param_bound(&mut self, bound: &'ast syn::TypeParamBound) {
|
||||||
|
match bound {
|
||||||
|
syn::TypeParamBound::Trait(bound) => self.visit_path(&bound.path),
|
||||||
|
syn::TypeParamBound::Lifetime(_) => {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Type parameter should not be considered used by a macro path.
|
// Type parameter should not be considered used by a macro path.
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ path = "lib.rs"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
proc-macro2 = "1.0"
|
proc-macro2 = "1.0"
|
||||||
quote = "1.0"
|
quote = "1.0"
|
||||||
syn = { version = "1.0.33", default-features = false, features = ["derive", "parsing", "printing", "clone-impls"] }
|
syn = { version = "1.0.60", default-features = false, features = ["derive", "parsing", "printing", "clone-impls"] }
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
targets = ["x86_64-unknown-linux-gnu"]
|
targets = ["x86_64-unknown-linux-gnu"]
|
||||||
|
|||||||
Reference in New Issue
Block a user