Factor out Type traversal to a Visit trait
diff --git a/syntax/mod.rs b/syntax/mod.rs
index 87e3454..5422681 100644
--- a/syntax/mod.rs
+++ b/syntax/mod.rs
@@ -27,6 +27,7 @@
mod toposort;
pub mod trivial;
pub mod types;
+mod visit;
use self::attrs::OtherAttrs;
use self::discriminant::Discriminant;
diff --git a/syntax/types.rs b/syntax/types.rs
index 031dc08..196a1db 100644
--- a/syntax/types.rs
+++ b/syntax/types.rs
@@ -5,6 +5,7 @@
use crate::syntax::resolve::Resolution;
use crate::syntax::set::{OrderedSet, UnorderedSet};
use crate::syntax::trivial::{self, TrivialReason};
+use crate::syntax::visit::{self, Visit};
use crate::syntax::{
toposort, Api, Atom, Enum, ExternType, Impl, Lifetimes, Pair, Struct, Type, TypeAlias,
};
@@ -41,28 +42,16 @@
let toposorted_structs = Vec::new();
fn visit<'a>(all: &mut OrderedSet<&'a Type>, ty: &'a Type) {
- all.insert(ty);
- match ty {
- Type::Ident(_) | Type::Str(_) | Type::Void(_) => {}
- Type::RustBox(ty)
- | Type::UniquePtr(ty)
- | Type::SharedPtr(ty)
- | Type::WeakPtr(ty)
- | Type::CxxVector(ty)
- | Type::RustVec(ty) => visit(all, &ty.inner),
- Type::Ref(r) => visit(all, &r.inner),
- Type::Ptr(p) => visit(all, &p.inner),
- Type::Array(a) => visit(all, &a.inner),
- Type::SliceRef(s) => visit(all, &s.inner),
- Type::Fn(f) => {
- if let Some(ret) = &f.ret {
- visit(all, ret);
- }
- for arg in &f.args {
- visit(all, &arg.ty);
- }
+ struct CollectTypes<'s, 'a>(&'s mut OrderedSet<&'a Type>);
+
+ impl<'s, 'a> Visit<'a> for CollectTypes<'s, 'a> {
+ fn visit_type(&mut self, ty: &'a Type) {
+ self.0.insert(ty);
+ visit::visit_type(self, ty);
}
}
+
+ CollectTypes(all).visit_type(ty);
}
let mut add_resolution = |name: &'a Pair, generics: &'a Lifetimes| {
diff --git a/syntax/visit.rs b/syntax/visit.rs
new file mode 100644
index 0000000..2f31378
--- /dev/null
+++ b/syntax/visit.rs
@@ -0,0 +1,34 @@
+use crate::syntax::Type;
+
+pub trait Visit<'a> {
+ fn visit_type(&mut self, ty: &'a Type) {
+ visit_type(self, ty);
+ }
+}
+
+pub fn visit_type<'a, V>(visitor: &mut V, ty: &'a Type)
+where
+ V: Visit<'a> + ?Sized,
+{
+ match ty {
+ Type::Ident(_) | Type::Str(_) | Type::Void(_) => {}
+ Type::RustBox(ty)
+ | Type::UniquePtr(ty)
+ | Type::SharedPtr(ty)
+ | Type::WeakPtr(ty)
+ | Type::CxxVector(ty)
+ | Type::RustVec(ty) => visitor.visit_type(&ty.inner),
+ Type::Ref(r) => visitor.visit_type(&r.inner),
+ Type::Ptr(p) => visitor.visit_type(&p.inner),
+ Type::Array(a) => visitor.visit_type(&a.inner),
+ Type::SliceRef(s) => visitor.visit_type(&s.inner),
+ Type::Fn(fun) => {
+ if let Some(ret) = &fun.ret {
+ visitor.visit_type(ret);
+ }
+ for arg in &fun.args {
+ visitor.visit_type(&arg.ty);
+ }
+ }
+ }
+}