]>
Commit | Line | Data |
---|---|---|
f035d41b XL |
1 | //! Visitor helpers |
2 | ||
f9f354fc XL |
3 | use crate::{BoundVar, DebruijnIndex, Interner, Visit, VisitResult, Visitor}; |
4 | ||
f035d41b | 5 | /// Visitor extensions. |
f9f354fc | 6 | pub trait VisitExt<I: Interner>: Visit<I> { |
f035d41b | 7 | /// Check whether there are free (non-bound) variables. |
f9f354fc XL |
8 | fn has_free_vars(&self, interner: &I) -> bool { |
9 | self.visit_with( | |
10 | &mut FindFreeVarsVisitor { interner }, | |
11 | DebruijnIndex::INNERMOST, | |
12 | ) | |
13 | .to_bool() | |
14 | } | |
15 | } | |
16 | ||
17 | impl<T, I: Interner> VisitExt<I> for T where T: Visit<I> {} | |
18 | ||
f035d41b | 19 | /// Helper visitor for finding a specific value. |
f9f354fc | 20 | #[derive(Clone, Copy, Debug, PartialEq, Eq)] |
f035d41b | 21 | #[allow(missing_docs)] |
f9f354fc XL |
22 | pub struct FindAny { |
23 | pub found: bool, | |
24 | } | |
25 | ||
26 | impl FindAny { | |
f035d41b | 27 | /// Visitor has found the value. |
f9f354fc XL |
28 | pub const FOUND: FindAny = FindAny { found: true }; |
29 | ||
f035d41b | 30 | /// Checks whether the value has been found. |
f9f354fc XL |
31 | pub fn to_bool(&self) -> bool { |
32 | self.found | |
33 | } | |
34 | } | |
35 | ||
36 | impl VisitResult for FindAny { | |
37 | fn new() -> Self { | |
38 | FindAny { found: false } | |
39 | } | |
40 | ||
41 | fn return_early(&self) -> bool { | |
42 | self.found | |
43 | } | |
44 | fn combine(self, other: Self) -> Self { | |
45 | FindAny { | |
46 | found: self.found || other.found, | |
47 | } | |
48 | } | |
49 | } | |
50 | ||
51 | struct FindFreeVarsVisitor<'i, I: Interner> { | |
52 | interner: &'i I, | |
53 | } | |
54 | ||
55 | impl<'i, I: Interner> Visitor<'i, I> for FindFreeVarsVisitor<'i, I> { | |
56 | type Result = FindAny; | |
57 | ||
58 | fn as_dyn(&mut self) -> &mut dyn Visitor<'i, I, Result = Self::Result> { | |
59 | self | |
60 | } | |
61 | ||
62 | fn interner(&self) -> &'i I { | |
63 | self.interner | |
64 | } | |
65 | ||
f035d41b | 66 | fn visit_free_var( |
f9f354fc XL |
67 | &mut self, |
68 | _bound_var: BoundVar, | |
69 | _outer_binder: DebruijnIndex, | |
70 | ) -> Self::Result { | |
71 | FindAny::FOUND | |
72 | } | |
73 | } |