mirror of
https://github.com/pezkuwichain/serde.git
synced 2026-06-15 21:21:01 +00:00
Merge pull request #416 from dtolnay/filter
Remove filter no longer necessary for rustc >=1.7
This commit is contained in:
@@ -1,5 +1,3 @@
|
|||||||
use std::collections::HashSet;
|
|
||||||
|
|
||||||
use aster::AstBuilder;
|
use aster::AstBuilder;
|
||||||
|
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
@@ -63,8 +61,6 @@ pub fn with_bound<F>(
|
|||||||
item.body.all_fields()
|
item.body.all_fields()
|
||||||
.filter(|&field| filter(&field.attrs))
|
.filter(|&field| filter(&field.attrs))
|
||||||
.map(|field| &field.ty)
|
.map(|field| &field.ty)
|
||||||
// TODO this filter can be removed later, see comment on function
|
|
||||||
.filter(|ty| contains_generic(ty, generics))
|
|
||||||
.filter(|ty| !contains_recursion(ty, item.ident))
|
.filter(|ty| !contains_recursion(ty, item.ident))
|
||||||
.map(|ty| strip_reference(ty))
|
.map(|ty| strip_reference(ty))
|
||||||
.map(|ty| builder.where_predicate()
|
.map(|ty| builder.where_predicate()
|
||||||
@@ -76,44 +72,6 @@ pub fn with_bound<F>(
|
|||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rust <1.7 enforces that `where` clauses involve generic type parameters. The
|
|
||||||
// corresponding compiler error is E0193. It is no longer enforced in Rust >=1.7
|
|
||||||
// so this filtering can be removed in the future when we stop supporting <1.7.
|
|
||||||
//
|
|
||||||
// E0193 means we must not generate a `where` clause like `i32: Serialize`
|
|
||||||
// because even though i32 implements Serialize, i32 is not a generic type
|
|
||||||
// parameter. Clauses like `T: Serialize` and `Option<T>: Serialize` are okay.
|
|
||||||
// This function decides whether a given type references any of the generic type
|
|
||||||
// parameters in the input `Generics`.
|
|
||||||
fn contains_generic(ty: &ast::Ty, generics: &ast::Generics) -> bool {
|
|
||||||
struct FindGeneric<'a> {
|
|
||||||
generic_names: &'a HashSet<ast::Name>,
|
|
||||||
found_generic: bool,
|
|
||||||
}
|
|
||||||
impl<'a, 'v> visit::Visitor<'v> for FindGeneric<'a> {
|
|
||||||
fn visit_path(&mut self, path: &'v ast::Path, _id: ast::NodeId) {
|
|
||||||
if !path.global
|
|
||||||
&& path.segments.len() == 1
|
|
||||||
&& self.generic_names.contains(&path.segments[0].identifier.name) {
|
|
||||||
self.found_generic = true;
|
|
||||||
} else {
|
|
||||||
visit::walk_path(self, path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let generic_names: HashSet<_> = generics.ty_params.iter()
|
|
||||||
.map(|ty_param| ty_param.ident.name)
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
let mut visitor = FindGeneric {
|
|
||||||
generic_names: &generic_names,
|
|
||||||
found_generic: false,
|
|
||||||
};
|
|
||||||
visit::walk_ty(&mut visitor, ty);
|
|
||||||
visitor.found_generic
|
|
||||||
}
|
|
||||||
|
|
||||||
// We do not attempt to generate any bounds based on field types that are
|
// We do not attempt to generate any bounds based on field types that are
|
||||||
// directly recursive, as in:
|
// directly recursive, as in:
|
||||||
//
|
//
|
||||||
|
|||||||
Reference in New Issue
Block a user