//! TypeVisitor helpers use crate::{BoundVar, ControlFlow, DebruijnIndex, Interner, TypeVisitable, TypeVisitor}; /// TypeVisitor extensions. pub trait VisitExt: TypeVisitable { /// Check whether there are free (non-bound) variables. fn has_free_vars(&self, interner: I) -> bool { let flow = self.visit_with( &mut FindFreeVarsVisitor { interner }, DebruijnIndex::INNERMOST, ); matches!(flow, ControlFlow::Break(_)) } } impl VisitExt for T where T: TypeVisitable {} struct FindFreeVarsVisitor { interner: I, } impl TypeVisitor for FindFreeVarsVisitor { type BreakTy = (); fn as_dyn(&mut self) -> &mut dyn TypeVisitor { self } fn interner(&self) -> I { self.interner } fn visit_free_var( &mut self, _bound_var: BoundVar, _outer_binder: DebruijnIndex, ) -> ControlFlow<()> { ControlFlow::Break(()) } }