From a17230db8c57ffd760dec2f6e735775c628c70cd Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 26 Mar 2021 17:30:13 -0400 Subject: [PATCH] Factor out Type traversal to a Visit trait --- syntax/mod.rs | 1 + syntax/types.rs | 29 +++++++++-------------------- syntax/visit.rs | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 20 deletions(-) create mode 100644 syntax/visit.rs diff --git a/syntax/mod.rs b/syntax/mod.rs index 87e34540c..5422681f2 100644 --- a/syntax/mod.rs +++ b/syntax/mod.rs @@ -27,6 +27,7 @@ mod tokens; 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 031dc08b1..196a1db99 100644 --- a/syntax/types.rs +++ b/syntax/types.rs @@ -5,6 +5,7 @@ use crate::syntax::report::Errors; 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 @@ impl<'a> Types<'a> { 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 000000000..2f31378f2 --- /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); + } + } + } +}