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