1#![warn(clippy::all, clippy::pedantic)]
3#![allow(clippy::wildcard_imports, clippy::missing_errors_doc)]
4use super::*;
5
6pub trait Visit<'a, A: AstTypes> {
7 type Error;
8
9 fn visit<W: Walk<'a, A> + ?Sized>(&mut self, walk: &'a W) -> Result<(), Self::Error> {
10 walk.visit_in(self)
11 }
12 fn visit_literal(&mut self, lit: &'a A::Literal) -> Result<(), Self::Error> {
13 let _ = lit;
14 Ok(())
15 }
16 fn visit_macro_id(&mut self, name: &'a A::MacroId) -> Result<(), Self::Error> {
17 let _ = name;
18 Ok(())
19 }
20 fn visit_symbol(&mut self, name: &'a A::Symbol) -> Result<(), Self::Error> {
21 let _ = name;
22 Ok(())
23 }
24 fn visit_path(&mut self, path: &'a A::Path) -> Result<(), Self::Error> {
25 let _ = path;
26 Ok(())
27 }
28 fn visit_expr(&mut self, expr: &'a Expr<A>) -> Result<(), Self::Error> {
29 expr.children(self)
30 }
31 fn visit_use(&mut self, item: &'a Use<A>) -> Result<(), Self::Error> {
32 item.children(self)
33 }
34 fn visit_pat(&mut self, item: &'a Pat<A>) -> Result<(), Self::Error> {
35 item.children(self)
36 }
37 fn visit_bind(&mut self, item: &'a Bind<A>) -> Result<(), Self::Error> {
38 item.children(self)
39 }
40 fn visit_make(&mut self, item: &'a Make<A>) -> Result<(), Self::Error> {
41 item.children(self)
42 }
43 fn visit_makearm(&mut self, item: &'a MakeArm<A>) -> Result<(), Self::Error> {
44 item.children(self)
45 }
46 fn visit_match(&mut self, item: &'a Match<A>) -> Result<(), Self::Error> {
47 item.children(self)
48 }
49 fn visit_matcharm(&mut self, item: &'a MatchArm<A>) -> Result<(), Self::Error> {
50 item.children(self)
51 }
52}
53
54pub trait Walk<'a, A: AstTypes> {
55 #[inline]
56 fn children<V: Visit<'a, A> + ?Sized>(&'a self, _v: &mut V) -> Result<(), V::Error> {
57 Ok(())
58 }
59 fn visit_in<V: Visit<'a, A> + ?Sized>(&'a self, v: &mut V) -> Result<(), V::Error>;
60}
61
62impl<'a, A: AstTypes> Walk<'a, A> for Expr<A> {
63 fn children<V: Visit<'a, A> + ?Sized>(&'a self, v: &mut V) -> Result<(), V::Error> {
64 match self {
65 Self::Omitted => Ok(()),
66 Self::Id(path) => v.visit_path(path),
67 Self::MetId(id) => v.visit_macro_id(id),
68 Self::Lit(lit) => v.visit_literal(lit),
69 Self::Use(u) => u.visit_in(v),
70 Self::Bind(bind) => bind.visit_in(v),
71 Self::Make(make) => make.visit_in(v),
72 Self::Match(mtch) => mtch.visit_in(v),
73 Self::Op(_op, exprs) => exprs.visit_in(v),
74 }
75 }
76
77 #[inline]
78 fn visit_in<V: Visit<'a, A> + ?Sized>(&'a self, v: &mut V) -> Result<(), V::Error> {
79 v.visit_expr(self)
80 }
81}
82
83impl<'a, A: AstTypes> Walk<'a, A> for Use<A> {
84 fn children<V: Visit<'a, A> + ?Sized>(&'a self, v: &mut V) -> Result<(), V::Error> {
85 match self {
86 Self::Glob => Ok(()),
87 Self::Name(name) => v.visit_symbol(name),
88 Self::Alias(name, alias) => {
89 v.visit_symbol(name)?;
90 v.visit_symbol(alias)
91 }
92 Self::Path(name, rest) => {
93 v.visit_symbol(name)?;
94 rest.visit_in(v)
95 }
96 Self::Tree(items) => items.visit_in(v),
97 }
98 }
99
100 #[inline]
101 fn visit_in<V: Visit<'a, A> + ?Sized>(&'a self, v: &mut V) -> Result<(), V::Error> {
102 v.visit_use(self)
103 }
104}
105
106impl<'a, A: AstTypes> Walk<'a, A> for Pat<A> {
107 fn children<V: Visit<'a, A> + ?Sized>(&'a self, v: &mut V) -> Result<(), V::Error> {
108 match self {
109 Self::Ignore | Self::Never => Ok(()),
110 Self::MetId(id) => v.visit_macro_id(id),
111 Self::Name(name) => v.visit_symbol(name),
112 Self::Value(literal) => literal.visit_in(v),
113 Self::Op(_, pats) => pats.visit_in(v),
114 }
115 }
116
117 #[inline]
118 fn visit_in<V: Visit<'a, A> + ?Sized>(&'a self, v: &mut V) -> Result<(), V::Error> {
119 v.visit_pat(self)
120 }
121}
122
123impl<'a, A: AstTypes> Walk<'a, A> for Bind<A> {
124 fn children<V: Visit<'a, A> + ?Sized>(&'a self, v: &mut V) -> Result<(), V::Error> {
125 let Self(_kind, gens, pat, exprs) = self;
126 gens.iter().try_for_each(|g| v.visit_path(g))?;
127 pat.visit_in(v)?;
128 exprs.visit_in(v)
129 }
130
131 #[inline]
132 fn visit_in<V: Visit<'a, A> + ?Sized>(&'a self, v: &mut V) -> Result<(), V::Error> {
133 v.visit_bind(self)
134 }
135}
136
137impl<'a, A: AstTypes> Walk<'a, A> for Make<A> {
138 fn children<V: Visit<'a, A> + ?Sized>(&'a self, v: &mut V) -> Result<(), V::Error> {
139 let Self(expr, arms) = self;
140 expr.visit_in(v)?;
141 arms.visit_in(v)
142 }
143
144 #[inline]
145 fn visit_in<V: Visit<'a, A> + ?Sized>(&'a self, v: &mut V) -> Result<(), V::Error> {
146 v.visit_make(self)
147 }
148}
149
150impl<'a, A: AstTypes> Walk<'a, A> for MakeArm<A> {
151 fn children<V: Visit<'a, A> + ?Sized>(&'a self, v: &mut V) -> Result<(), V::Error> {
152 let Self(name, expr) = self;
153 v.visit_symbol(name)?;
154 expr.visit_in(v)
155 }
156
157 #[inline]
158 fn visit_in<V: Visit<'a, A> + ?Sized>(&'a self, v: &mut V) -> Result<(), V::Error> {
159 v.visit_makearm(self)
160 }
161}
162
163impl<'a, A: AstTypes> Walk<'a, A> for Match<A> {
164 fn children<V: Visit<'a, A> + ?Sized>(&'a self, v: &mut V) -> Result<(), V::Error> {
165 let Self(expr, arms) = self;
166 expr.visit_in(v)?;
167 arms.visit_in(v)
168 }
169
170 #[inline]
171 fn visit_in<V: Visit<'a, A> + ?Sized>(&'a self, v: &mut V) -> Result<(), V::Error> {
172 v.visit_match(self)
173 }
174}
175
176impl<'a, A: AstTypes> Walk<'a, A> for MatchArm<A> {
177 fn children<V: Visit<'a, A> + ?Sized>(&'a self, v: &mut V) -> Result<(), V::Error> {
178 let Self(name, expr) = self;
179 name.visit_in(v)?;
180 expr.visit_in(v)
181 }
182
183 #[inline]
184 fn visit_in<V: Visit<'a, A> + ?Sized>(&'a self, v: &mut V) -> Result<(), V::Error> {
185 v.visit_matcharm(self)
186 }
187}
188
189impl<'a, T: Annotation + Walk<'a, A>, A: AstTypes> Walk<'a, A> for At<T, A> {
190 #[inline]
191 fn children<V: Visit<'a, A> + ?Sized>(&'a self, v: &mut V) -> Result<(), V::Error> {
192 self.0.children(v)
193 }
194
195 #[inline]
196 fn visit_in<V: Visit<'a, A> + ?Sized>(&'a self, v: &mut V) -> Result<(), V::Error> {
197 self.0.visit_in(v)
198 }
199}
200
201impl<'a, T: Walk<'a, A>, A: AstTypes> Walk<'a, A> for [T] {
206 fn children<V: Visit<'a, A> + ?Sized>(&'a self, v: &mut V) -> Result<(), V::Error> {
207 for item in self {
208 item.visit_in(v)?;
209 }
210 Ok(())
211 }
212
213 fn visit_in<V: Visit<'a, A> + ?Sized>(&'a self, v: &mut V) -> Result<(), V::Error> {
214 for item in self {
215 item.visit_in(v)?;
216 }
217 Ok(())
218 }
219}
220
221impl<'a, T: Walk<'a, A>, A: AstTypes> Walk<'a, A> for Vec<T> {
222 fn children<V: Visit<'a, A> + ?Sized>(&'a self, v: &mut V) -> Result<(), V::Error> {
223 self.as_slice().children(v)
224 }
225
226 fn visit_in<V: Visit<'a, A> + ?Sized>(&'a self, v: &mut V) -> Result<(), V::Error> {
227 self.as_slice().visit_in(v)
228 }
229}
230
231impl<'a, T: Walk<'a, A>, A: AstTypes> Walk<'a, A> for Option<T> {
232 fn children<V: Visit<'a, A> + ?Sized>(&'a self, v: &mut V) -> Result<(), V::Error> {
233 match self {
234 Some(t) => t.children(v),
235 _ => Ok(()),
236 }
237 }
238 fn visit_in<V: Visit<'a, A> + ?Sized>(&'a self, v: &mut V) -> Result<(), V::Error> {
239 match self {
240 Some(t) => t.visit_in(v),
241 _ => Ok(()),
242 }
243 }
244}
245
246