chalk_ir/visit/
visitors.rs

1//! TypeVisitor helpers
2
3use crate::{BoundVar, ControlFlow, DebruijnIndex, Interner, TypeVisitable, TypeVisitor};
4
5/// TypeVisitor extensions.
6pub trait VisitExt<I: Interner>: TypeVisitable<I> {
7    /// Check whether there are free (non-bound) variables.
8    fn has_free_vars(&self, interner: I) -> bool {
9        let flow = self.visit_with(
10            &mut FindFreeVarsVisitor { interner },
11            DebruijnIndex::INNERMOST,
12        );
13        matches!(flow, ControlFlow::Break(_))
14    }
15}
16
17impl<T, I: Interner> VisitExt<I> for T where T: TypeVisitable<I> {}
18
19struct FindFreeVarsVisitor<I: Interner> {
20    interner: I,
21}
22
23impl<I: Interner> TypeVisitor<I> for FindFreeVarsVisitor<I> {
24    type BreakTy = ();
25
26    fn as_dyn(&mut self) -> &mut dyn TypeVisitor<I, BreakTy = Self::BreakTy> {
27        self
28    }
29
30    fn interner(&self) -> I {
31        self.interner
32    }
33
34    fn visit_free_var(
35        &mut self,
36        _bound_var: BoundVar,
37        _outer_binder: DebruijnIndex,
38    ) -> ControlFlow<()> {
39        ControlFlow::Break(())
40    }
41}