]>
Commit | Line | Data |
---|---|---|
e1599b0c | 1 | //! A `MutVisitor` represents an AST modification; it accepts an AST piece and |
a2a8927a | 2 | //! mutates it in place. So, for instance, macro expansion is a `MutVisitor` |
9fa01778 XL |
3 | //! that walks over an AST and modifies it. |
4 | //! | |
e1599b0c | 5 | //! Note: using a `MutVisitor` (other than the `MacroExpander` `MutVisitor`) on |
9fa01778 | 6 | //! an AST before macro expansion is probably a bad idea. For instance, |
e1599b0c | 7 | //! a `MutVisitor` renaming item names in a module will miss all of those |
9fa01778 XL |
8 | //! that are created by the expansion of a macro. |
9 | ||
10 | use crate::ast::*; | |
9fa01778 | 11 | use crate::ptr::P; |
dfeec247 | 12 | use crate::token::{self, Token}; |
9fa01778 | 13 | use crate::tokenstream::*; |
9fa01778 | 14 | |
ba9703b0 | 15 | use rustc_data_structures::map_in_place::MapInPlace; |
9fa01778 | 16 | use rustc_data_structures::sync::Lrc; |
a2a8927a | 17 | use rustc_data_structures::thin_vec::ThinVec; |
1b1a35ee | 18 | use rustc_span::source_map::Spanned; |
f9f354fc | 19 | use rustc_span::symbol::Ident; |
dfeec247 XL |
20 | use rustc_span::Span; |
21 | ||
22 | use smallvec::{smallvec, Array, SmallVec}; | |
9fa01778 | 23 | use std::ops::DerefMut; |
a2a8927a | 24 | use std::{panic, ptr}; |
9fa01778 XL |
25 | |
26 | pub trait ExpectOne<A: Array> { | |
27 | fn expect_one(self, err: &'static str) -> A::Item; | |
28 | } | |
29 | ||
30 | impl<A: Array> ExpectOne<A> for SmallVec<A> { | |
31 | fn expect_one(self, err: &'static str) -> A::Item { | |
5869c6ff | 32 | assert!(self.len() == 1, "{}", err); |
9fa01778 XL |
33 | self.into_iter().next().unwrap() |
34 | } | |
35 | } | |
36 | ||
37 | pub trait MutVisitor: Sized { | |
29967ef6 XL |
38 | /// Mutable token visiting only exists for the `macro_rules` token marker and should not be |
39 | /// used otherwise. Token visitor would be entirely separate from the regular visitor if | |
40 | /// the marker didn't have to visit AST fragments in nonterminal tokens. | |
3c0e092e | 41 | const VISIT_TOKENS: bool = false; |
29967ef6 | 42 | |
9fa01778 XL |
43 | // Methods in this trait have one of three forms: |
44 | // | |
45 | // fn visit_t(&mut self, t: &mut T); // common | |
46 | // fn flat_map_t(&mut self, t: T) -> SmallVec<[T; 1]>; // rare | |
47 | // fn filter_map_t(&mut self, t: T) -> Option<T>; // rarest | |
48 | // | |
49 | // Any additions to this trait should happen in form of a call to a public | |
50 | // `noop_*` function that only calls out to the visitor again, not other | |
51 | // `noop_*` functions. This is a necessary API workaround to the problem of | |
52 | // not being able to call out to the super default method in an overridden | |
53 | // default method. | |
54 | // | |
55 | // When writing these methods, it is better to use destructuring like this: | |
56 | // | |
57 | // fn visit_abc(&mut self, ABC { a, b, c: _ }: &mut ABC) { | |
58 | // visit_a(a); | |
59 | // visit_b(b); | |
60 | // } | |
61 | // | |
62 | // than to use field access like this: | |
63 | // | |
64 | // fn visit_abc(&mut self, abc: &mut ABC) { | |
65 | // visit_a(&mut abc.a); | |
66 | // visit_b(&mut abc.b); | |
67 | // // ignore abc.c | |
68 | // } | |
69 | // | |
70 | // As well as being more concise, the former is explicit about which fields | |
71 | // are skipped. Furthermore, if a new field is added, the destructuring | |
72 | // version will cause a compile error, which is good. In comparison, the | |
73 | // field access version will continue working and it would be easy to | |
74 | // forget to add handling for it. | |
75 | ||
76 | fn visit_crate(&mut self, c: &mut Crate) { | |
77 | noop_visit_crate(c, self) | |
78 | } | |
79 | ||
80 | fn visit_meta_list_item(&mut self, list_item: &mut NestedMetaItem) { | |
81 | noop_visit_meta_list_item(list_item, self); | |
82 | } | |
83 | ||
84 | fn visit_meta_item(&mut self, meta_item: &mut MetaItem) { | |
85 | noop_visit_meta_item(meta_item, self); | |
86 | } | |
87 | ||
88 | fn visit_use_tree(&mut self, use_tree: &mut UseTree) { | |
89 | noop_visit_use_tree(use_tree, self); | |
90 | } | |
91 | ||
74b04a01 | 92 | fn flat_map_foreign_item(&mut self, ni: P<ForeignItem>) -> SmallVec<[P<ForeignItem>; 1]> { |
9fa01778 XL |
93 | noop_flat_map_foreign_item(ni, self) |
94 | } | |
95 | ||
96 | fn flat_map_item(&mut self, i: P<Item>) -> SmallVec<[P<Item>; 1]> { | |
97 | noop_flat_map_item(i, self) | |
98 | } | |
99 | ||
100 | fn visit_fn_header(&mut self, header: &mut FnHeader) { | |
101 | noop_visit_fn_header(header, self); | |
102 | } | |
103 | ||
6a06907d XL |
104 | fn flat_map_field_def(&mut self, fd: FieldDef) -> SmallVec<[FieldDef; 1]> { |
105 | noop_flat_map_field_def(fd, self) | |
9fa01778 XL |
106 | } |
107 | ||
108 | fn visit_item_kind(&mut self, i: &mut ItemKind) { | |
109 | noop_visit_item_kind(i, self); | |
110 | } | |
111 | ||
74b04a01 | 112 | fn flat_map_trait_item(&mut self, i: P<AssocItem>) -> SmallVec<[P<AssocItem>; 1]> { |
dfeec247 | 113 | noop_flat_map_assoc_item(i, self) |
9fa01778 XL |
114 | } |
115 | ||
74b04a01 | 116 | fn flat_map_impl_item(&mut self, i: P<AssocItem>) -> SmallVec<[P<AssocItem>; 1]> { |
dfeec247 | 117 | noop_flat_map_assoc_item(i, self) |
9fa01778 XL |
118 | } |
119 | ||
120 | fn visit_fn_decl(&mut self, d: &mut P<FnDecl>) { | |
121 | noop_visit_fn_decl(d, self); | |
122 | } | |
123 | ||
74b04a01 | 124 | fn visit_asyncness(&mut self, a: &mut Async) { |
9fa01778 XL |
125 | noop_visit_asyncness(a, self); |
126 | } | |
127 | ||
128 | fn visit_block(&mut self, b: &mut P<Block>) { | |
129 | noop_visit_block(b, self); | |
130 | } | |
131 | ||
132 | fn flat_map_stmt(&mut self, s: Stmt) -> SmallVec<[Stmt; 1]> { | |
133 | noop_flat_map_stmt(s, self) | |
134 | } | |
135 | ||
e1599b0c XL |
136 | fn flat_map_arm(&mut self, arm: Arm) -> SmallVec<[Arm; 1]> { |
137 | noop_flat_map_arm(arm, self) | |
9fa01778 XL |
138 | } |
139 | ||
9fa01778 XL |
140 | fn visit_pat(&mut self, p: &mut P<Pat>) { |
141 | noop_visit_pat(p, self); | |
142 | } | |
143 | ||
144 | fn visit_anon_const(&mut self, c: &mut AnonConst) { | |
145 | noop_visit_anon_const(c, self); | |
146 | } | |
147 | ||
148 | fn visit_expr(&mut self, e: &mut P<Expr>) { | |
149 | noop_visit_expr(e, self); | |
150 | } | |
151 | ||
152 | fn filter_map_expr(&mut self, e: P<Expr>) -> Option<P<Expr>> { | |
153 | noop_filter_map_expr(e, self) | |
154 | } | |
155 | ||
156 | fn visit_generic_arg(&mut self, arg: &mut GenericArg) { | |
157 | noop_visit_generic_arg(arg, self); | |
158 | } | |
159 | ||
160 | fn visit_ty(&mut self, t: &mut P<Ty>) { | |
161 | noop_visit_ty(t, self); | |
162 | } | |
163 | ||
164 | fn visit_lifetime(&mut self, l: &mut Lifetime) { | |
165 | noop_visit_lifetime(l, self); | |
166 | } | |
167 | ||
5099ac24 FG |
168 | fn visit_constraint(&mut self, t: &mut AssocConstraint) { |
169 | noop_visit_constraint(t, self); | |
9fa01778 XL |
170 | } |
171 | ||
9fa01778 XL |
172 | fn visit_foreign_mod(&mut self, nm: &mut ForeignMod) { |
173 | noop_visit_foreign_mod(nm, self); | |
174 | } | |
175 | ||
dfeec247 | 176 | fn flat_map_variant(&mut self, v: Variant) -> SmallVec<[Variant; 1]> { |
e1599b0c | 177 | noop_flat_map_variant(v, self) |
9fa01778 XL |
178 | } |
179 | ||
180 | fn visit_ident(&mut self, i: &mut Ident) { | |
181 | noop_visit_ident(i, self); | |
182 | } | |
183 | ||
184 | fn visit_path(&mut self, p: &mut Path) { | |
185 | noop_visit_path(p, self); | |
186 | } | |
187 | ||
188 | fn visit_qself(&mut self, qs: &mut Option<QSelf>) { | |
189 | noop_visit_qself(qs, self); | |
190 | } | |
191 | ||
192 | fn visit_generic_args(&mut self, p: &mut GenericArgs) { | |
193 | noop_visit_generic_args(p, self); | |
194 | } | |
195 | ||
196 | fn visit_angle_bracketed_parameter_data(&mut self, p: &mut AngleBracketedArgs) { | |
197 | noop_visit_angle_bracketed_parameter_data(p, self); | |
198 | } | |
199 | ||
200 | fn visit_parenthesized_parameter_data(&mut self, p: &mut ParenthesizedArgs) { | |
201 | noop_visit_parenthesized_parameter_data(p, self); | |
202 | } | |
203 | ||
204 | fn visit_local(&mut self, l: &mut P<Local>) { | |
205 | noop_visit_local(l, self); | |
206 | } | |
207 | ||
29967ef6 XL |
208 | fn visit_mac_call(&mut self, mac: &mut MacCall) { |
209 | noop_visit_mac(mac, self); | |
9fa01778 XL |
210 | } |
211 | ||
212 | fn visit_macro_def(&mut self, def: &mut MacroDef) { | |
213 | noop_visit_macro_def(def, self); | |
214 | } | |
215 | ||
216 | fn visit_label(&mut self, label: &mut Label) { | |
217 | noop_visit_label(label, self); | |
218 | } | |
219 | ||
220 | fn visit_attribute(&mut self, at: &mut Attribute) { | |
221 | noop_visit_attribute(at, self); | |
222 | } | |
223 | ||
e1599b0c XL |
224 | fn flat_map_param(&mut self, param: Param) -> SmallVec<[Param; 1]> { |
225 | noop_flat_map_param(param, self) | |
9fa01778 XL |
226 | } |
227 | ||
228 | fn visit_generics(&mut self, generics: &mut Generics) { | |
229 | noop_visit_generics(generics, self); | |
230 | } | |
231 | ||
232 | fn visit_trait_ref(&mut self, tr: &mut TraitRef) { | |
233 | noop_visit_trait_ref(tr, self); | |
234 | } | |
235 | ||
236 | fn visit_poly_trait_ref(&mut self, p: &mut PolyTraitRef) { | |
237 | noop_visit_poly_trait_ref(p, self); | |
238 | } | |
239 | ||
240 | fn visit_variant_data(&mut self, vdata: &mut VariantData) { | |
241 | noop_visit_variant_data(vdata, self); | |
242 | } | |
243 | ||
e1599b0c XL |
244 | fn flat_map_generic_param(&mut self, param: GenericParam) -> SmallVec<[GenericParam; 1]> { |
245 | noop_flat_map_generic_param(param, self) | |
9fa01778 XL |
246 | } |
247 | ||
9fa01778 XL |
248 | fn visit_param_bound(&mut self, tpb: &mut GenericBound) { |
249 | noop_visit_param_bound(tpb, self); | |
250 | } | |
251 | ||
252 | fn visit_mt(&mut self, mt: &mut MutTy) { | |
253 | noop_visit_mt(mt, self); | |
254 | } | |
255 | ||
6a06907d XL |
256 | fn flat_map_expr_field(&mut self, f: ExprField) -> SmallVec<[ExprField; 1]> { |
257 | noop_flat_map_expr_field(f, self) | |
9fa01778 XL |
258 | } |
259 | ||
260 | fn visit_where_clause(&mut self, where_clause: &mut WhereClause) { | |
261 | noop_visit_where_clause(where_clause, self); | |
262 | } | |
263 | ||
264 | fn visit_where_predicate(&mut self, where_predicate: &mut WherePredicate) { | |
265 | noop_visit_where_predicate(where_predicate, self); | |
266 | } | |
267 | ||
268 | fn visit_vis(&mut self, vis: &mut Visibility) { | |
269 | noop_visit_vis(vis, self); | |
270 | } | |
271 | ||
272 | fn visit_id(&mut self, _id: &mut NodeId) { | |
273 | // Do nothing. | |
274 | } | |
275 | ||
276 | fn visit_span(&mut self, _sp: &mut Span) { | |
277 | // Do nothing. | |
278 | } | |
e1599b0c | 279 | |
6a06907d XL |
280 | fn flat_map_pat_field(&mut self, fp: PatField) -> SmallVec<[PatField; 1]> { |
281 | noop_flat_map_pat_field(fp, self) | |
e1599b0c | 282 | } |
9fa01778 XL |
283 | } |
284 | ||
285 | /// Use a map-style function (`FnOnce(T) -> T`) to overwrite a `&mut T`. Useful | |
286 | /// when using a `flat_map_*` or `filter_map_*` method within a `visit_` | |
a2a8927a | 287 | /// method. |
9fa01778 XL |
288 | // |
289 | // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. | |
a2a8927a | 290 | pub fn visit_clobber<T: DummyAstNode>(t: &mut T, f: impl FnOnce(T) -> T) { |
532ac7d7 XL |
291 | unsafe { |
292 | // Safe because `t` is used in a read-only fashion by `read()` before | |
293 | // being overwritten by `write()`. | |
294 | let old_t = ptr::read(t); | |
a2a8927a XL |
295 | let new_t = |
296 | panic::catch_unwind(panic::AssertUnwindSafe(|| f(old_t))).unwrap_or_else(|err| { | |
297 | // Set `t` to some valid but possible meaningless value, | |
298 | // and pass the fatal error further. | |
299 | ptr::write(t, T::dummy()); | |
300 | panic::resume_unwind(err); | |
301 | }); | |
532ac7d7 XL |
302 | ptr::write(t, new_t); |
303 | } | |
9fa01778 XL |
304 | } |
305 | ||
306 | // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. | |
307 | #[inline] | |
dfeec247 XL |
308 | pub fn visit_vec<T, F>(elems: &mut Vec<T>, mut visit_elem: F) |
309 | where | |
310 | F: FnMut(&mut T), | |
311 | { | |
9fa01778 XL |
312 | for elem in elems { |
313 | visit_elem(elem); | |
314 | } | |
315 | } | |
316 | ||
317 | // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. | |
318 | #[inline] | |
dfeec247 XL |
319 | pub fn visit_opt<T, F>(opt: &mut Option<T>, mut visit_elem: F) |
320 | where | |
321 | F: FnMut(&mut T), | |
322 | { | |
9fa01778 XL |
323 | if let Some(elem) = opt { |
324 | visit_elem(elem); | |
325 | } | |
326 | } | |
327 | ||
328 | // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. | |
329 | pub fn visit_attrs<T: MutVisitor>(attrs: &mut Vec<Attribute>, vis: &mut T) { | |
330 | visit_vec(attrs, |attr| vis.visit_attribute(attr)); | |
331 | } | |
332 | ||
333 | // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. | |
dfeec247 | 334 | pub fn visit_thin_attrs<T: MutVisitor>(attrs: &mut AttrVec, vis: &mut T) { |
9fa01778 XL |
335 | for attr in attrs.iter_mut() { |
336 | vis.visit_attribute(attr); | |
337 | } | |
338 | } | |
339 | ||
340 | // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. | |
341 | pub fn visit_exprs<T: MutVisitor>(exprs: &mut Vec<P<Expr>>, vis: &mut T) { | |
342 | exprs.flat_map_in_place(|expr| vis.filter_map_expr(expr)) | |
343 | } | |
344 | ||
345 | // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. | |
346 | pub fn visit_bounds<T: MutVisitor>(bounds: &mut GenericBounds, vis: &mut T) { | |
347 | visit_vec(bounds, |bound| vis.visit_param_bound(bound)); | |
348 | } | |
349 | ||
350 | // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. | |
3dfed10e | 351 | pub fn visit_fn_sig<T: MutVisitor>(FnSig { header, decl, span }: &mut FnSig, vis: &mut T) { |
9fa01778 XL |
352 | vis.visit_fn_header(header); |
353 | vis.visit_fn_decl(decl); | |
3dfed10e | 354 | vis.visit_span(span); |
9fa01778 XL |
355 | } |
356 | ||
60c5eb7d XL |
357 | // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. |
358 | pub fn visit_mac_args<T: MutVisitor>(args: &mut MacArgs, vis: &mut T) { | |
359 | match args { | |
360 | MacArgs::Empty => {} | |
361 | MacArgs::Delimited(dspan, _delim, tokens) => { | |
362 | visit_delim_span(dspan, vis); | |
29967ef6 | 363 | visit_tts(tokens, vis); |
60c5eb7d | 364 | } |
5869c6ff | 365 | MacArgs::Eq(eq_span, token) => { |
60c5eb7d | 366 | vis.visit_span(eq_span); |
3c0e092e | 367 | if T::VISIT_TOKENS { |
5869c6ff XL |
368 | visit_token(token, vis); |
369 | } else { | |
370 | // The value in `#[key = VALUE]` must be visited as an expression for backward | |
371 | // compatibility, so that macros can be expanded in that position. | |
372 | match &mut token.kind { | |
373 | token::Interpolated(nt) => match Lrc::make_mut(nt) { | |
374 | token::NtExpr(expr) => vis.visit_expr(expr), | |
fc512014 XL |
375 | t => panic!("unexpected token in key-value attribute: {:?}", t), |
376 | }, | |
377 | t => panic!("unexpected token in key-value attribute: {:?}", t), | |
29967ef6 XL |
378 | } |
379 | } | |
60c5eb7d XL |
380 | } |
381 | } | |
382 | } | |
383 | ||
384 | pub fn visit_delim_span<T: MutVisitor>(dspan: &mut DelimSpan, vis: &mut T) { | |
385 | vis.visit_span(&mut dspan.open); | |
386 | vis.visit_span(&mut dspan.close); | |
387 | } | |
388 | ||
6a06907d XL |
389 | pub fn noop_flat_map_pat_field<T: MutVisitor>( |
390 | mut fp: PatField, | |
e1599b0c | 391 | vis: &mut T, |
6a06907d XL |
392 | ) -> SmallVec<[PatField; 1]> { |
393 | let PatField { attrs, id, ident, is_placeholder: _, is_shorthand: _, pat, span } = &mut fp; | |
e1599b0c XL |
394 | vis.visit_id(id); |
395 | vis.visit_ident(ident); | |
396 | vis.visit_pat(pat); | |
397 | vis.visit_span(span); | |
398 | visit_thin_attrs(attrs, vis); | |
399 | smallvec![fp] | |
400 | } | |
401 | ||
9fa01778 XL |
402 | pub fn noop_visit_use_tree<T: MutVisitor>(use_tree: &mut UseTree, vis: &mut T) { |
403 | let UseTree { prefix, kind, span } = use_tree; | |
404 | vis.visit_path(prefix); | |
405 | match kind { | |
406 | UseTreeKind::Simple(rename, id1, id2) => { | |
407 | visit_opt(rename, |rename| vis.visit_ident(rename)); | |
408 | vis.visit_id(id1); | |
409 | vis.visit_id(id2); | |
410 | } | |
411 | UseTreeKind::Nested(items) => { | |
412 | for (tree, id) in items { | |
413 | vis.visit_use_tree(tree); | |
414 | vis.visit_id(id); | |
415 | } | |
416 | } | |
417 | UseTreeKind::Glob => {} | |
418 | } | |
419 | vis.visit_span(span); | |
420 | } | |
421 | ||
e1599b0c XL |
422 | pub fn noop_flat_map_arm<T: MutVisitor>(mut arm: Arm, vis: &mut T) -> SmallVec<[Arm; 1]> { |
423 | let Arm { attrs, pat, guard, body, span, id, is_placeholder: _ } = &mut arm; | |
136023e0 | 424 | visit_thin_attrs(attrs, vis); |
e1599b0c XL |
425 | vis.visit_id(id); |
426 | vis.visit_pat(pat); | |
dc9dc135 | 427 | visit_opt(guard, |guard| vis.visit_expr(guard)); |
9fa01778 | 428 | vis.visit_expr(body); |
dc9dc135 | 429 | vis.visit_span(span); |
e1599b0c | 430 | smallvec![arm] |
9fa01778 XL |
431 | } |
432 | ||
5099ac24 FG |
433 | pub fn noop_visit_constraint<T: MutVisitor>( |
434 | AssocConstraint { id, ident, gen_args, kind, span }: &mut AssocConstraint, | |
dfeec247 | 435 | vis: &mut T, |
dc9dc135 | 436 | ) { |
9fa01778 XL |
437 | vis.visit_id(id); |
438 | vis.visit_ident(ident); | |
fc512014 XL |
439 | if let Some(ref mut gen_args) = gen_args { |
440 | vis.visit_generic_args(gen_args); | |
441 | } | |
dc9dc135 | 442 | match kind { |
5099ac24 FG |
443 | AssocConstraintKind::Equality { ref mut term } => match term { |
444 | Term::Ty(ty) => vis.visit_ty(ty), | |
445 | Term::Const(c) => vis.visit_anon_const(c), | |
446 | }, | |
447 | AssocConstraintKind::Bound { ref mut bounds } => visit_bounds(bounds, vis), | |
dc9dc135 | 448 | } |
9fa01778 XL |
449 | vis.visit_span(span); |
450 | } | |
451 | ||
452 | pub fn noop_visit_ty<T: MutVisitor>(ty: &mut P<Ty>, vis: &mut T) { | |
29967ef6 | 453 | let Ty { id, kind, span, tokens } = ty.deref_mut(); |
9fa01778 | 454 | vis.visit_id(id); |
e74abb32 | 455 | match kind { |
dfeec247 | 456 | TyKind::Infer | TyKind::ImplicitSelf | TyKind::Err | TyKind::Never | TyKind::CVarArgs => {} |
9fa01778 XL |
457 | TyKind::Slice(ty) => vis.visit_ty(ty), |
458 | TyKind::Ptr(mt) => vis.visit_mt(mt), | |
459 | TyKind::Rptr(lt, mt) => { | |
460 | visit_opt(lt, |lt| noop_visit_lifetime(lt, vis)); | |
461 | vis.visit_mt(mt); | |
462 | } | |
463 | TyKind::BareFn(bft) => { | |
3c0e092e XL |
464 | let BareFnTy { unsafety, ext: _, generic_params, decl } = bft.deref_mut(); |
465 | visit_unsafety(unsafety, vis); | |
e1599b0c | 466 | generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param)); |
9fa01778 XL |
467 | vis.visit_fn_decl(decl); |
468 | } | |
469 | TyKind::Tup(tys) => visit_vec(tys, |ty| vis.visit_ty(ty)), | |
470 | TyKind::Paren(ty) => vis.visit_ty(ty), | |
471 | TyKind::Path(qself, path) => { | |
472 | vis.visit_qself(qself); | |
473 | vis.visit_path(path); | |
474 | } | |
475 | TyKind::Array(ty, length) => { | |
476 | vis.visit_ty(ty); | |
477 | vis.visit_anon_const(length); | |
478 | } | |
479 | TyKind::Typeof(expr) => vis.visit_anon_const(expr), | |
dfeec247 XL |
480 | TyKind::TraitObject(bounds, _syntax) => { |
481 | visit_vec(bounds, |bound| vis.visit_param_bound(bound)) | |
482 | } | |
9fa01778 XL |
483 | TyKind::ImplTrait(id, bounds) => { |
484 | vis.visit_id(id); | |
485 | visit_vec(bounds, |bound| vis.visit_param_bound(bound)); | |
486 | } | |
29967ef6 | 487 | TyKind::MacCall(mac) => vis.visit_mac_call(mac), |
9fa01778 XL |
488 | } |
489 | vis.visit_span(span); | |
29967ef6 | 490 | visit_lazy_tts(tokens, vis); |
9fa01778 XL |
491 | } |
492 | ||
493 | pub fn noop_visit_foreign_mod<T: MutVisitor>(foreign_mod: &mut ForeignMod, vis: &mut T) { | |
3c0e092e XL |
494 | let ForeignMod { unsafety, abi: _, items } = foreign_mod; |
495 | visit_unsafety(unsafety, vis); | |
9fa01778 XL |
496 | items.flat_map_in_place(|item| vis.flat_map_foreign_item(item)); |
497 | } | |
498 | ||
dfeec247 XL |
499 | pub fn noop_flat_map_variant<T: MutVisitor>( |
500 | mut variant: Variant, | |
501 | visitor: &mut T, | |
502 | ) -> SmallVec<[Variant; 1]> { | |
60c5eb7d XL |
503 | let Variant { ident, vis, attrs, id, data, disr_expr, span, is_placeholder: _ } = &mut variant; |
504 | visitor.visit_ident(ident); | |
505 | visitor.visit_vis(vis); | |
136023e0 | 506 | visit_thin_attrs(attrs, visitor); |
60c5eb7d XL |
507 | visitor.visit_id(id); |
508 | visitor.visit_variant_data(data); | |
509 | visit_opt(disr_expr, |disr_expr| visitor.visit_anon_const(disr_expr)); | |
510 | visitor.visit_span(span); | |
e1599b0c | 511 | smallvec![variant] |
9fa01778 XL |
512 | } |
513 | ||
514 | pub fn noop_visit_ident<T: MutVisitor>(Ident { name: _, span }: &mut Ident, vis: &mut T) { | |
515 | vis.visit_span(span); | |
516 | } | |
517 | ||
29967ef6 | 518 | pub fn noop_visit_path<T: MutVisitor>(Path { segments, span, tokens }: &mut Path, vis: &mut T) { |
9fa01778 XL |
519 | vis.visit_span(span); |
520 | for PathSegment { ident, id, args } in segments { | |
521 | vis.visit_ident(ident); | |
522 | vis.visit_id(id); | |
523 | visit_opt(args, |args| vis.visit_generic_args(args)); | |
524 | } | |
29967ef6 | 525 | visit_lazy_tts(tokens, vis); |
9fa01778 XL |
526 | } |
527 | ||
528 | pub fn noop_visit_qself<T: MutVisitor>(qself: &mut Option<QSelf>, vis: &mut T) { | |
529 | visit_opt(qself, |QSelf { ty, path_span, position: _ }| { | |
530 | vis.visit_ty(ty); | |
531 | vis.visit_span(path_span); | |
532 | }) | |
533 | } | |
534 | ||
535 | pub fn noop_visit_generic_args<T: MutVisitor>(generic_args: &mut GenericArgs, vis: &mut T) { | |
536 | match generic_args { | |
537 | GenericArgs::AngleBracketed(data) => vis.visit_angle_bracketed_parameter_data(data), | |
538 | GenericArgs::Parenthesized(data) => vis.visit_parenthesized_parameter_data(data), | |
539 | } | |
540 | } | |
541 | ||
542 | pub fn noop_visit_generic_arg<T: MutVisitor>(arg: &mut GenericArg, vis: &mut T) { | |
543 | match arg { | |
544 | GenericArg::Lifetime(lt) => vis.visit_lifetime(lt), | |
545 | GenericArg::Type(ty) => vis.visit_ty(ty), | |
546 | GenericArg::Const(ct) => vis.visit_anon_const(ct), | |
547 | } | |
548 | } | |
549 | ||
dfeec247 XL |
550 | pub fn noop_visit_angle_bracketed_parameter_data<T: MutVisitor>( |
551 | data: &mut AngleBracketedArgs, | |
552 | vis: &mut T, | |
553 | ) { | |
ba9703b0 XL |
554 | let AngleBracketedArgs { args, span } = data; |
555 | visit_vec(args, |arg| match arg { | |
556 | AngleBracketedArg::Arg(arg) => vis.visit_generic_arg(arg), | |
5099ac24 | 557 | AngleBracketedArg::Constraint(constraint) => vis.visit_constraint(constraint), |
ba9703b0 | 558 | }); |
9fa01778 XL |
559 | vis.visit_span(span); |
560 | } | |
561 | ||
dfeec247 XL |
562 | pub fn noop_visit_parenthesized_parameter_data<T: MutVisitor>( |
563 | args: &mut ParenthesizedArgs, | |
564 | vis: &mut T, | |
565 | ) { | |
5869c6ff | 566 | let ParenthesizedArgs { inputs, output, span, .. } = args; |
9fa01778 | 567 | visit_vec(inputs, |input| vis.visit_ty(input)); |
dfeec247 | 568 | noop_visit_fn_ret_ty(output, vis); |
9fa01778 XL |
569 | vis.visit_span(span); |
570 | } | |
571 | ||
572 | pub fn noop_visit_local<T: MutVisitor>(local: &mut P<Local>, vis: &mut T) { | |
94222f64 | 573 | let Local { id, pat, ty, kind, span, attrs, tokens } = local.deref_mut(); |
9fa01778 XL |
574 | vis.visit_id(id); |
575 | vis.visit_pat(pat); | |
576 | visit_opt(ty, |ty| vis.visit_ty(ty)); | |
94222f64 XL |
577 | match kind { |
578 | LocalKind::Decl => {} | |
579 | LocalKind::Init(init) => { | |
580 | vis.visit_expr(init); | |
581 | } | |
582 | LocalKind::InitElse(init, els) => { | |
583 | vis.visit_expr(init); | |
584 | vis.visit_block(els); | |
585 | } | |
586 | } | |
9fa01778 XL |
587 | vis.visit_span(span); |
588 | visit_thin_attrs(attrs, vis); | |
fc512014 | 589 | visit_lazy_tts(tokens, vis); |
9fa01778 XL |
590 | } |
591 | ||
592 | pub fn noop_visit_attribute<T: MutVisitor>(attr: &mut Attribute, vis: &mut T) { | |
60c5eb7d XL |
593 | let Attribute { kind, id: _, style: _, span } = attr; |
594 | match kind { | |
29967ef6 | 595 | AttrKind::Normal(AttrItem { path, args, tokens }, attr_tokens) => { |
60c5eb7d XL |
596 | vis.visit_path(path); |
597 | visit_mac_args(args, vis); | |
29967ef6 XL |
598 | visit_lazy_tts(tokens, vis); |
599 | visit_lazy_tts(attr_tokens, vis); | |
60c5eb7d | 600 | } |
3dfed10e | 601 | AttrKind::DocComment(..) => {} |
60c5eb7d | 602 | } |
9fa01778 XL |
603 | vis.visit_span(span); |
604 | } | |
605 | ||
ba9703b0 XL |
606 | pub fn noop_visit_mac<T: MutVisitor>(mac: &mut MacCall, vis: &mut T) { |
607 | let MacCall { path, args, prior_type_ascription: _ } = mac; | |
9fa01778 | 608 | vis.visit_path(path); |
60c5eb7d | 609 | visit_mac_args(args, vis); |
9fa01778 XL |
610 | } |
611 | ||
612 | pub fn noop_visit_macro_def<T: MutVisitor>(macro_def: &mut MacroDef, vis: &mut T) { | |
ba9703b0 | 613 | let MacroDef { body, macro_rules: _ } = macro_def; |
60c5eb7d | 614 | visit_mac_args(body, vis); |
9fa01778 XL |
615 | } |
616 | ||
617 | pub fn noop_visit_meta_list_item<T: MutVisitor>(li: &mut NestedMetaItem, vis: &mut T) { | |
532ac7d7 XL |
618 | match li { |
619 | NestedMetaItem::MetaItem(mi) => vis.visit_meta_item(mi), | |
620 | NestedMetaItem::Literal(_lit) => {} | |
9fa01778 | 621 | } |
9fa01778 XL |
622 | } |
623 | ||
624 | pub fn noop_visit_meta_item<T: MutVisitor>(mi: &mut MetaItem, vis: &mut T) { | |
e74abb32 XL |
625 | let MetaItem { path: _, kind, span } = mi; |
626 | match kind { | |
9fa01778 XL |
627 | MetaItemKind::Word => {} |
628 | MetaItemKind::List(mis) => visit_vec(mis, |mi| vis.visit_meta_list_item(mi)), | |
629 | MetaItemKind::NameValue(_s) => {} | |
630 | } | |
631 | vis.visit_span(span); | |
632 | } | |
633 | ||
e1599b0c XL |
634 | pub fn noop_flat_map_param<T: MutVisitor>(mut param: Param, vis: &mut T) -> SmallVec<[Param; 1]> { |
635 | let Param { attrs, id, pat, span, ty, is_placeholder: _ } = &mut param; | |
9fa01778 | 636 | vis.visit_id(id); |
dc9dc135 | 637 | visit_thin_attrs(attrs, vis); |
9fa01778 | 638 | vis.visit_pat(pat); |
416331ca | 639 | vis.visit_span(span); |
9fa01778 | 640 | vis.visit_ty(ty); |
e1599b0c | 641 | smallvec![param] |
9fa01778 XL |
642 | } |
643 | ||
cdc7bbd5 XL |
644 | // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. |
645 | pub fn visit_attr_annotated_tt<T: MutVisitor>(tt: &mut AttrAnnotatedTokenTree, vis: &mut T) { | |
646 | match tt { | |
647 | AttrAnnotatedTokenTree::Token(token) => { | |
648 | visit_token(token, vis); | |
649 | } | |
650 | AttrAnnotatedTokenTree::Delimited(DelimSpan { open, close }, _delim, tts) => { | |
651 | vis.visit_span(open); | |
652 | vis.visit_span(close); | |
653 | visit_attr_annotated_tts(tts, vis); | |
654 | } | |
655 | AttrAnnotatedTokenTree::Attributes(data) => { | |
656 | for attr in &mut *data.attrs { | |
657 | match &mut attr.kind { | |
658 | AttrKind::Normal(_, attr_tokens) => { | |
659 | visit_lazy_tts(attr_tokens, vis); | |
660 | } | |
661 | AttrKind::DocComment(..) => { | |
662 | vis.visit_span(&mut attr.span); | |
663 | } | |
664 | } | |
665 | } | |
666 | visit_lazy_tts_opt_mut(Some(&mut data.tokens), vis); | |
667 | } | |
668 | } | |
669 | } | |
670 | ||
29967ef6 XL |
671 | // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. |
672 | pub fn visit_tt<T: MutVisitor>(tt: &mut TokenTree, vis: &mut T) { | |
9fa01778 | 673 | match tt { |
dc9dc135 | 674 | TokenTree::Token(token) => { |
29967ef6 | 675 | visit_token(token, vis); |
9fa01778 XL |
676 | } |
677 | TokenTree::Delimited(DelimSpan { open, close }, _delim, tts) => { | |
678 | vis.visit_span(open); | |
679 | vis.visit_span(close); | |
29967ef6 | 680 | visit_tts(tts, vis); |
9fa01778 XL |
681 | } |
682 | } | |
683 | } | |
684 | ||
29967ef6 XL |
685 | // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. |
686 | pub fn visit_tts<T: MutVisitor>(TokenStream(tts): &mut TokenStream, vis: &mut T) { | |
3c0e092e | 687 | if T::VISIT_TOKENS && !tts.is_empty() { |
29967ef6 XL |
688 | let tts = Lrc::make_mut(tts); |
689 | visit_vec(tts, |(tree, _is_joint)| visit_tt(tree, vis)); | |
690 | } | |
691 | } | |
692 | ||
cdc7bbd5 XL |
693 | pub fn visit_attr_annotated_tts<T: MutVisitor>( |
694 | AttrAnnotatedTokenStream(tts): &mut AttrAnnotatedTokenStream, | |
695 | vis: &mut T, | |
696 | ) { | |
3c0e092e | 697 | if T::VISIT_TOKENS && !tts.is_empty() { |
cdc7bbd5 XL |
698 | let tts = Lrc::make_mut(tts); |
699 | visit_vec(tts, |(tree, _is_joint)| visit_attr_annotated_tt(tree, vis)); | |
700 | } | |
701 | } | |
702 | ||
703 | pub fn visit_lazy_tts_opt_mut<T: MutVisitor>(lazy_tts: Option<&mut LazyTokenStream>, vis: &mut T) { | |
3c0e092e | 704 | if T::VISIT_TOKENS { |
cdc7bbd5 | 705 | if let Some(lazy_tts) = lazy_tts { |
29967ef6 | 706 | let mut tts = lazy_tts.create_token_stream(); |
cdc7bbd5 | 707 | visit_attr_annotated_tts(&mut tts, vis); |
29967ef6 | 708 | *lazy_tts = LazyTokenStream::new(tts); |
cdc7bbd5 | 709 | } |
29967ef6 | 710 | } |
9fa01778 XL |
711 | } |
712 | ||
cdc7bbd5 XL |
713 | pub fn visit_lazy_tts<T: MutVisitor>(lazy_tts: &mut Option<LazyTokenStream>, vis: &mut T) { |
714 | visit_lazy_tts_opt_mut(lazy_tts.as_mut(), vis); | |
715 | } | |
716 | ||
29967ef6 | 717 | // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. |
e1599b0c | 718 | // Applies ident visitor if it's an ident; applies other visits to interpolated nodes. |
dc9dc135 XL |
719 | // In practice the ident part is not actually used by specific visitors right now, |
720 | // but there's a test below checking that it works. | |
29967ef6 | 721 | pub fn visit_token<T: MutVisitor>(t: &mut Token, vis: &mut T) { |
dc9dc135 XL |
722 | let Token { kind, span } = t; |
723 | match kind { | |
724 | token::Ident(name, _) | token::Lifetime(name) => { | |
725 | let mut ident = Ident::new(*name, *span); | |
726 | vis.visit_ident(&mut ident); | |
727 | *name = ident.name; | |
728 | *span = ident.span; | |
e1599b0c | 729 | return; // Avoid visiting the span for the second time. |
dc9dc135 | 730 | } |
9fa01778 XL |
731 | token::Interpolated(nt) => { |
732 | let mut nt = Lrc::make_mut(nt); | |
29967ef6 | 733 | visit_interpolated(&mut nt, vis); |
9fa01778 XL |
734 | } |
735 | _ => {} | |
736 | } | |
dc9dc135 | 737 | vis.visit_span(span); |
9fa01778 XL |
738 | } |
739 | ||
29967ef6 | 740 | // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. |
e1599b0c | 741 | /// Applies the visitor to elements of interpolated nodes. |
9fa01778 XL |
742 | // |
743 | // N.B., this can occur only when applying a visitor to partially expanded | |
744 | // code, where parsed pieces have gotten implanted ito *other* macro | |
745 | // invocations. This is relevant for macro hygiene, but possibly not elsewhere. | |
746 | // | |
747 | // One problem here occurs because the types for flat_map_item, flat_map_stmt, | |
e1599b0c | 748 | // etc., allow the visitor to return *multiple* items; this is a problem for the |
9fa01778 XL |
749 | // nodes here, because they insist on having exactly one piece. One solution |
750 | // would be to mangle the MutVisitor trait to include one-to-many and | |
751 | // one-to-one versions of these entry points, but that would probably confuse a | |
752 | // lot of people and help very few. Instead, I'm just going to put in dynamic | |
753 | // checks. I think the performance impact of this will be pretty much | |
e1599b0c | 754 | // nonexistent. The danger is that someone will apply a `MutVisitor` to a |
9fa01778 | 755 | // partially expanded node, and will be confused by the fact that their |
e1599b0c | 756 | // `flat_map_item` or `flat_map_stmt` isn't getting called on `NtItem` or `NtStmt` |
9fa01778 XL |
757 | // nodes. Hopefully they'll wind up reading this comment, and doing something |
758 | // appropriate. | |
759 | // | |
e1599b0c | 760 | // BTW, design choice: I considered just changing the type of, e.g., `NtItem` to |
9fa01778 | 761 | // contain multiple items, but decided against it when I looked at |
e1599b0c | 762 | // `parse_item_or_view_item` and tried to figure out what I would do with |
9fa01778 | 763 | // multiple items there.... |
29967ef6 | 764 | pub fn visit_interpolated<T: MutVisitor>(nt: &mut token::Nonterminal, vis: &mut T) { |
9fa01778 | 765 | match nt { |
dfeec247 XL |
766 | token::NtItem(item) => visit_clobber(item, |item| { |
767 | // This is probably okay, because the only visitors likely to | |
768 | // peek inside interpolated nodes will be renamings/markings, | |
769 | // which map single items to single items. | |
770 | vis.flat_map_item(item).expect_one("expected visitor to produce exactly one item") | |
771 | }), | |
9fa01778 | 772 | token::NtBlock(block) => vis.visit_block(block), |
dfeec247 XL |
773 | token::NtStmt(stmt) => visit_clobber(stmt, |stmt| { |
774 | // See reasoning above. | |
775 | vis.flat_map_stmt(stmt).expect_one("expected visitor to produce exactly one item") | |
776 | }), | |
9fa01778 XL |
777 | token::NtPat(pat) => vis.visit_pat(pat), |
778 | token::NtExpr(expr) => vis.visit_expr(expr), | |
779 | token::NtTy(ty) => vis.visit_ty(ty), | |
780 | token::NtIdent(ident, _is_raw) => vis.visit_ident(ident), | |
781 | token::NtLifetime(ident) => vis.visit_ident(ident), | |
782 | token::NtLiteral(expr) => vis.visit_expr(expr), | |
74b04a01 | 783 | token::NtMeta(item) => { |
29967ef6 | 784 | let AttrItem { path, args, tokens } = item.deref_mut(); |
e74abb32 | 785 | vis.visit_path(path); |
60c5eb7d | 786 | visit_mac_args(args, vis); |
29967ef6 | 787 | visit_lazy_tts(tokens, vis); |
e74abb32 | 788 | } |
9fa01778 | 789 | token::NtPath(path) => vis.visit_path(path), |
9fa01778 | 790 | token::NtVis(visib) => vis.visit_vis(visib), |
9fa01778 XL |
791 | } |
792 | } | |
793 | ||
3c0e092e XL |
794 | // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. |
795 | pub fn visit_defaultness<T: MutVisitor>(defaultness: &mut Defaultness, vis: &mut T) { | |
796 | match defaultness { | |
797 | Defaultness::Default(span) => vis.visit_span(span), | |
798 | Defaultness::Final => {} | |
799 | } | |
800 | } | |
801 | ||
802 | // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. | |
803 | pub fn visit_unsafety<T: MutVisitor>(unsafety: &mut Unsafe, vis: &mut T) { | |
804 | match unsafety { | |
805 | Unsafe::Yes(span) => vis.visit_span(span), | |
806 | Unsafe::No => {} | |
807 | } | |
808 | } | |
809 | ||
810 | // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. | |
811 | pub fn visit_polarity<T: MutVisitor>(polarity: &mut ImplPolarity, vis: &mut T) { | |
812 | match polarity { | |
813 | ImplPolarity::Positive => {} | |
814 | ImplPolarity::Negative(span) => vis.visit_span(span), | |
815 | } | |
816 | } | |
817 | ||
818 | // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. | |
819 | pub fn visit_constness<T: MutVisitor>(constness: &mut Const, vis: &mut T) { | |
820 | match constness { | |
821 | Const::Yes(span) => vis.visit_span(span), | |
822 | Const::No => {} | |
823 | } | |
824 | } | |
825 | ||
74b04a01 | 826 | pub fn noop_visit_asyncness<T: MutVisitor>(asyncness: &mut Async, vis: &mut T) { |
9fa01778 | 827 | match asyncness { |
74b04a01 | 828 | Async::Yes { span: _, closure_id, return_impl_trait_id } => { |
9fa01778 XL |
829 | vis.visit_id(closure_id); |
830 | vis.visit_id(return_impl_trait_id); | |
831 | } | |
74b04a01 | 832 | Async::No => {} |
9fa01778 XL |
833 | } |
834 | } | |
835 | ||
836 | pub fn noop_visit_fn_decl<T: MutVisitor>(decl: &mut P<FnDecl>, vis: &mut T) { | |
e74abb32 | 837 | let FnDecl { inputs, output } = decl.deref_mut(); |
e1599b0c | 838 | inputs.flat_map_in_place(|param| vis.flat_map_param(param)); |
dfeec247 XL |
839 | noop_visit_fn_ret_ty(output, vis); |
840 | } | |
841 | ||
74b04a01 | 842 | pub fn noop_visit_fn_ret_ty<T: MutVisitor>(fn_ret_ty: &mut FnRetTy, vis: &mut T) { |
dfeec247 | 843 | match fn_ret_ty { |
74b04a01 XL |
844 | FnRetTy::Default(span) => vis.visit_span(span), |
845 | FnRetTy::Ty(ty) => vis.visit_ty(ty), | |
9fa01778 XL |
846 | } |
847 | } | |
848 | ||
849 | pub fn noop_visit_param_bound<T: MutVisitor>(pb: &mut GenericBound, vis: &mut T) { | |
850 | match pb { | |
851 | GenericBound::Trait(ty, _modifier) => vis.visit_poly_trait_ref(ty), | |
852 | GenericBound::Outlives(lifetime) => noop_visit_lifetime(lifetime, vis), | |
853 | } | |
854 | } | |
855 | ||
e1599b0c XL |
856 | pub fn noop_flat_map_generic_param<T: MutVisitor>( |
857 | mut param: GenericParam, | |
dfeec247 XL |
858 | vis: &mut T, |
859 | ) -> SmallVec<[GenericParam; 1]> { | |
e1599b0c | 860 | let GenericParam { id, ident, attrs, bounds, kind, is_placeholder: _ } = &mut param; |
9fa01778 XL |
861 | vis.visit_id(id); |
862 | vis.visit_ident(ident); | |
863 | visit_thin_attrs(attrs, vis); | |
864 | visit_vec(bounds, |bound| noop_visit_param_bound(bound, vis)); | |
865 | match kind { | |
866 | GenericParamKind::Lifetime => {} | |
867 | GenericParamKind::Type { default } => { | |
868 | visit_opt(default, |default| vis.visit_ty(default)); | |
869 | } | |
5869c6ff | 870 | GenericParamKind::Const { ty, kw_span: _, default } => { |
9fa01778 | 871 | vis.visit_ty(ty); |
5869c6ff | 872 | visit_opt(default, |default| vis.visit_anon_const(default)); |
9fa01778 XL |
873 | } |
874 | } | |
e1599b0c | 875 | smallvec![param] |
9fa01778 XL |
876 | } |
877 | ||
878 | pub fn noop_visit_label<T: MutVisitor>(Label { ident }: &mut Label, vis: &mut T) { | |
879 | vis.visit_ident(ident); | |
880 | } | |
881 | ||
882 | fn noop_visit_lifetime<T: MutVisitor>(Lifetime { id, ident }: &mut Lifetime, vis: &mut T) { | |
883 | vis.visit_id(id); | |
884 | vis.visit_ident(ident); | |
885 | } | |
886 | ||
887 | pub fn noop_visit_generics<T: MutVisitor>(generics: &mut Generics, vis: &mut T) { | |
888 | let Generics { params, where_clause, span } = generics; | |
e1599b0c | 889 | params.flat_map_in_place(|param| vis.flat_map_generic_param(param)); |
9fa01778 XL |
890 | vis.visit_where_clause(where_clause); |
891 | vis.visit_span(span); | |
892 | } | |
893 | ||
894 | pub fn noop_visit_where_clause<T: MutVisitor>(wc: &mut WhereClause, vis: &mut T) { | |
f035d41b | 895 | let WhereClause { has_where_token: _, predicates, span } = wc; |
9fa01778 XL |
896 | visit_vec(predicates, |predicate| vis.visit_where_predicate(predicate)); |
897 | vis.visit_span(span); | |
898 | } | |
899 | ||
900 | pub fn noop_visit_where_predicate<T: MutVisitor>(pred: &mut WherePredicate, vis: &mut T) { | |
901 | match pred { | |
902 | WherePredicate::BoundPredicate(bp) => { | |
903 | let WhereBoundPredicate { span, bound_generic_params, bounded_ty, bounds } = bp; | |
904 | vis.visit_span(span); | |
e1599b0c | 905 | bound_generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param)); |
9fa01778 XL |
906 | vis.visit_ty(bounded_ty); |
907 | visit_vec(bounds, |bound| vis.visit_param_bound(bound)); | |
908 | } | |
909 | WherePredicate::RegionPredicate(rp) => { | |
910 | let WhereRegionPredicate { span, lifetime, bounds } = rp; | |
911 | vis.visit_span(span); | |
912 | noop_visit_lifetime(lifetime, vis); | |
913 | visit_vec(bounds, |bound| noop_visit_param_bound(bound, vis)); | |
914 | } | |
915 | WherePredicate::EqPredicate(ep) => { | |
916 | let WhereEqPredicate { id, span, lhs_ty, rhs_ty } = ep; | |
917 | vis.visit_id(id); | |
918 | vis.visit_span(span); | |
919 | vis.visit_ty(lhs_ty); | |
920 | vis.visit_ty(rhs_ty); | |
921 | } | |
922 | } | |
923 | } | |
924 | ||
925 | pub fn noop_visit_variant_data<T: MutVisitor>(vdata: &mut VariantData, vis: &mut T) { | |
926 | match vdata { | |
e1599b0c | 927 | VariantData::Struct(fields, ..) => { |
6a06907d | 928 | fields.flat_map_in_place(|field| vis.flat_map_field_def(field)); |
dfeec247 | 929 | } |
9fa01778 | 930 | VariantData::Tuple(fields, id) => { |
6a06907d | 931 | fields.flat_map_in_place(|field| vis.flat_map_field_def(field)); |
9fa01778 | 932 | vis.visit_id(id); |
dfeec247 | 933 | } |
9fa01778 XL |
934 | VariantData::Unit(id) => vis.visit_id(id), |
935 | } | |
936 | } | |
937 | ||
938 | pub fn noop_visit_trait_ref<T: MutVisitor>(TraitRef { path, ref_id }: &mut TraitRef, vis: &mut T) { | |
939 | vis.visit_path(path); | |
940 | vis.visit_id(ref_id); | |
941 | } | |
942 | ||
943 | pub fn noop_visit_poly_trait_ref<T: MutVisitor>(p: &mut PolyTraitRef, vis: &mut T) { | |
944 | let PolyTraitRef { bound_generic_params, trait_ref, span } = p; | |
e1599b0c | 945 | bound_generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param)); |
9fa01778 XL |
946 | vis.visit_trait_ref(trait_ref); |
947 | vis.visit_span(span); | |
948 | } | |
949 | ||
6a06907d XL |
950 | pub fn noop_flat_map_field_def<T: MutVisitor>( |
951 | mut fd: FieldDef, | |
dfeec247 | 952 | visitor: &mut T, |
6a06907d XL |
953 | ) -> SmallVec<[FieldDef; 1]> { |
954 | let FieldDef { span, ident, vis, id, ty, attrs, is_placeholder: _ } = &mut fd; | |
9fa01778 XL |
955 | visitor.visit_span(span); |
956 | visit_opt(ident, |ident| visitor.visit_ident(ident)); | |
957 | visitor.visit_vis(vis); | |
958 | visitor.visit_id(id); | |
959 | visitor.visit_ty(ty); | |
136023e0 | 960 | visit_thin_attrs(attrs, visitor); |
6a06907d | 961 | smallvec![fd] |
9fa01778 XL |
962 | } |
963 | ||
6a06907d XL |
964 | pub fn noop_flat_map_expr_field<T: MutVisitor>( |
965 | mut f: ExprField, | |
966 | vis: &mut T, | |
967 | ) -> SmallVec<[ExprField; 1]> { | |
968 | let ExprField { ident, expr, span, is_shorthand: _, attrs, id, is_placeholder: _ } = &mut f; | |
9fa01778 XL |
969 | vis.visit_ident(ident); |
970 | vis.visit_expr(expr); | |
e1599b0c | 971 | vis.visit_id(id); |
9fa01778 XL |
972 | vis.visit_span(span); |
973 | visit_thin_attrs(attrs, vis); | |
e1599b0c | 974 | smallvec![f] |
9fa01778 XL |
975 | } |
976 | ||
977 | pub fn noop_visit_mt<T: MutVisitor>(MutTy { ty, mutbl: _ }: &mut MutTy, vis: &mut T) { | |
978 | vis.visit_ty(ty); | |
979 | } | |
980 | ||
981 | pub fn noop_visit_block<T: MutVisitor>(block: &mut P<Block>, vis: &mut T) { | |
94222f64 | 982 | let Block { id, stmts, rules: _, span, tokens, could_be_bare_literal: _ } = block.deref_mut(); |
9fa01778 XL |
983 | vis.visit_id(id); |
984 | stmts.flat_map_in_place(|stmt| vis.flat_map_stmt(stmt)); | |
985 | vis.visit_span(span); | |
29967ef6 | 986 | visit_lazy_tts(tokens, vis); |
9fa01778 XL |
987 | } |
988 | ||
989 | pub fn noop_visit_item_kind<T: MutVisitor>(kind: &mut ItemKind, vis: &mut T) { | |
990 | match kind { | |
991 | ItemKind::ExternCrate(_orig_name) => {} | |
992 | ItemKind::Use(use_tree) => vis.visit_use_tree(use_tree), | |
3c0e092e | 993 | ItemKind::Static(ty, _, expr) => { |
9fa01778 | 994 | vis.visit_ty(ty); |
74b04a01 | 995 | visit_opt(expr, |expr| vis.visit_expr(expr)); |
9fa01778 | 996 | } |
3c0e092e XL |
997 | ItemKind::Const(defaultness, ty, expr) => { |
998 | visit_defaultness(defaultness, vis); | |
999 | vis.visit_ty(ty); | |
1000 | visit_opt(expr, |expr| vis.visit_expr(expr)); | |
1001 | } | |
1002 | ItemKind::Fn(box Fn { defaultness, generics, sig, body }) => { | |
1003 | visit_defaultness(defaultness, vis); | |
60c5eb7d | 1004 | visit_fn_sig(sig, vis); |
9fa01778 | 1005 | vis.visit_generics(generics); |
74b04a01 | 1006 | visit_opt(body, |body| vis.visit_block(body)); |
9fa01778 | 1007 | } |
3c0e092e XL |
1008 | ItemKind::Mod(unsafety, mod_kind) => { |
1009 | visit_unsafety(unsafety, vis); | |
1010 | match mod_kind { | |
5e7ed085 | 1011 | ModKind::Loaded(items, _inline, ModSpans { inner_span, inject_use_span }) => { |
3c0e092e | 1012 | vis.visit_span(inner_span); |
5e7ed085 | 1013 | vis.visit_span(inject_use_span); |
3c0e092e XL |
1014 | items.flat_map_in_place(|item| vis.flat_map_item(item)); |
1015 | } | |
1016 | ModKind::Unloaded => {} | |
6a06907d | 1017 | } |
3c0e092e | 1018 | } |
9fa01778 | 1019 | ItemKind::ForeignMod(nm) => vis.visit_foreign_mod(nm), |
17df50a5 | 1020 | ItemKind::GlobalAsm(asm) => noop_visit_inline_asm(asm, vis), |
5e7ed085 FG |
1021 | ItemKind::TyAlias(box TyAlias { |
1022 | defaultness, generics, where_clauses, bounds, ty, .. | |
1023 | }) => { | |
3c0e092e | 1024 | visit_defaultness(defaultness, vis); |
9fa01778 | 1025 | vis.visit_generics(generics); |
5e7ed085 FG |
1026 | vis.visit_span(&mut where_clauses.0.1); |
1027 | vis.visit_span(&mut where_clauses.1.1); | |
74b04a01 XL |
1028 | visit_bounds(bounds, vis); |
1029 | visit_opt(ty, |ty| vis.visit_ty(ty)); | |
9fa01778 | 1030 | } |
9fa01778 | 1031 | ItemKind::Enum(EnumDef { variants }, generics) => { |
e1599b0c | 1032 | variants.flat_map_in_place(|variant| vis.flat_map_variant(variant)); |
9fa01778 XL |
1033 | vis.visit_generics(generics); |
1034 | } | |
dfeec247 | 1035 | ItemKind::Struct(variant_data, generics) | ItemKind::Union(variant_data, generics) => { |
9fa01778 XL |
1036 | vis.visit_variant_data(variant_data); |
1037 | vis.visit_generics(generics); | |
1038 | } | |
3c0e092e XL |
1039 | ItemKind::Impl(box Impl { |
1040 | defaultness, | |
1041 | unsafety, | |
dfeec247 | 1042 | generics, |
3c0e092e XL |
1043 | constness, |
1044 | polarity, | |
dfeec247 XL |
1045 | of_trait, |
1046 | self_ty, | |
1047 | items, | |
5869c6ff | 1048 | }) => { |
3c0e092e XL |
1049 | visit_defaultness(defaultness, vis); |
1050 | visit_unsafety(unsafety, vis); | |
9fa01778 | 1051 | vis.visit_generics(generics); |
3c0e092e XL |
1052 | visit_constness(constness, vis); |
1053 | visit_polarity(polarity, vis); | |
dfeec247 XL |
1054 | visit_opt(of_trait, |trait_ref| vis.visit_trait_ref(trait_ref)); |
1055 | vis.visit_ty(self_ty); | |
9fa01778 XL |
1056 | items.flat_map_in_place(|item| vis.flat_map_impl_item(item)); |
1057 | } | |
3c0e092e XL |
1058 | ItemKind::Trait(box Trait { unsafety, is_auto: _, generics, bounds, items }) => { |
1059 | visit_unsafety(unsafety, vis); | |
9fa01778 XL |
1060 | vis.visit_generics(generics); |
1061 | visit_bounds(bounds, vis); | |
1062 | items.flat_map_in_place(|item| vis.flat_map_trait_item(item)); | |
1063 | } | |
1064 | ItemKind::TraitAlias(generics, bounds) => { | |
1065 | vis.visit_generics(generics); | |
1066 | visit_bounds(bounds, vis); | |
1067 | } | |
29967ef6 | 1068 | ItemKind::MacCall(m) => vis.visit_mac_call(m), |
9fa01778 XL |
1069 | ItemKind::MacroDef(def) => vis.visit_macro_def(def), |
1070 | } | |
1071 | } | |
1072 | ||
dfeec247 | 1073 | pub fn noop_flat_map_assoc_item<T: MutVisitor>( |
74b04a01 | 1074 | mut item: P<AssocItem>, |
dfeec247 | 1075 | visitor: &mut T, |
74b04a01 | 1076 | ) -> SmallVec<[P<AssocItem>; 1]> { |
29967ef6 | 1077 | let Item { id, ident, vis, attrs, kind, span, tokens } = item.deref_mut(); |
60c5eb7d XL |
1078 | visitor.visit_id(id); |
1079 | visitor.visit_ident(ident); | |
1080 | visitor.visit_vis(vis); | |
1081 | visit_attrs(attrs, visitor); | |
e74abb32 | 1082 | match kind { |
3c0e092e XL |
1083 | AssocItemKind::Const(defaultness, ty, expr) => { |
1084 | visit_defaultness(defaultness, visitor); | |
60c5eb7d | 1085 | visitor.visit_ty(ty); |
dfeec247 | 1086 | visit_opt(expr, |expr| visitor.visit_expr(expr)); |
9fa01778 | 1087 | } |
3c0e092e XL |
1088 | AssocItemKind::Fn(box Fn { defaultness, generics, sig, body }) => { |
1089 | visit_defaultness(defaultness, visitor); | |
74b04a01 | 1090 | visitor.visit_generics(generics); |
60c5eb7d XL |
1091 | visit_fn_sig(sig, visitor); |
1092 | visit_opt(body, |body| visitor.visit_block(body)); | |
9fa01778 | 1093 | } |
5e7ed085 FG |
1094 | AssocItemKind::TyAlias(box TyAlias { |
1095 | defaultness, | |
1096 | generics, | |
1097 | where_clauses, | |
1098 | bounds, | |
1099 | ty, | |
1100 | .. | |
1101 | }) => { | |
3c0e092e | 1102 | visit_defaultness(defaultness, visitor); |
74b04a01 | 1103 | visitor.visit_generics(generics); |
5e7ed085 FG |
1104 | visitor.visit_span(&mut where_clauses.0.1); |
1105 | visitor.visit_span(&mut where_clauses.1.1); | |
60c5eb7d | 1106 | visit_bounds(bounds, visitor); |
dfeec247 | 1107 | visit_opt(ty, |ty| visitor.visit_ty(ty)); |
9fa01778 | 1108 | } |
29967ef6 | 1109 | AssocItemKind::MacCall(mac) => visitor.visit_mac_call(mac), |
9fa01778 XL |
1110 | } |
1111 | visitor.visit_span(span); | |
29967ef6 | 1112 | visit_lazy_tts(tokens, visitor); |
9fa01778 XL |
1113 | smallvec![item] |
1114 | } | |
1115 | ||
1116 | pub fn noop_visit_fn_header<T: MutVisitor>(header: &mut FnHeader, vis: &mut T) { | |
3c0e092e XL |
1117 | let FnHeader { unsafety, asyncness, constness, ext: _ } = header; |
1118 | visit_constness(constness, vis); | |
74b04a01 | 1119 | vis.visit_asyncness(asyncness); |
3c0e092e | 1120 | visit_unsafety(unsafety, vis); |
9fa01778 XL |
1121 | } |
1122 | ||
9fa01778 | 1123 | pub fn noop_visit_crate<T: MutVisitor>(krate: &mut Crate, vis: &mut T) { |
5e7ed085 | 1124 | let Crate { attrs, items, spans, id, is_placeholder: _ } = krate; |
a2a8927a XL |
1125 | vis.visit_id(id); |
1126 | visit_attrs(attrs, vis); | |
1127 | items.flat_map_in_place(|item| vis.flat_map_item(item)); | |
5e7ed085 FG |
1128 | let ModSpans { inner_span, inject_use_span } = spans; |
1129 | vis.visit_span(inner_span); | |
1130 | vis.visit_span(inject_use_span); | |
9fa01778 XL |
1131 | } |
1132 | ||
e1599b0c | 1133 | // Mutates one item into possibly many items. |
dfeec247 XL |
1134 | pub fn noop_flat_map_item<T: MutVisitor>( |
1135 | mut item: P<Item>, | |
1136 | visitor: &mut T, | |
1137 | ) -> SmallVec<[P<Item>; 1]> { | |
29967ef6 | 1138 | let Item { ident, attrs, id, kind, vis, span, tokens } = item.deref_mut(); |
9fa01778 XL |
1139 | visitor.visit_ident(ident); |
1140 | visit_attrs(attrs, visitor); | |
1141 | visitor.visit_id(id); | |
e74abb32 | 1142 | visitor.visit_item_kind(kind); |
9fa01778 XL |
1143 | visitor.visit_vis(vis); |
1144 | visitor.visit_span(span); | |
29967ef6 | 1145 | visit_lazy_tts(tokens, visitor); |
9fa01778 XL |
1146 | |
1147 | smallvec![item] | |
1148 | } | |
1149 | ||
dfeec247 | 1150 | pub fn noop_flat_map_foreign_item<T: MutVisitor>( |
74b04a01 | 1151 | mut item: P<ForeignItem>, |
dfeec247 | 1152 | visitor: &mut T, |
74b04a01 | 1153 | ) -> SmallVec<[P<ForeignItem>; 1]> { |
29967ef6 | 1154 | let Item { ident, attrs, id, kind, vis, span, tokens } = item.deref_mut(); |
74b04a01 | 1155 | visitor.visit_id(id); |
9fa01778 | 1156 | visitor.visit_ident(ident); |
74b04a01 | 1157 | visitor.visit_vis(vis); |
9fa01778 | 1158 | visit_attrs(attrs, visitor); |
e74abb32 | 1159 | match kind { |
74b04a01 XL |
1160 | ForeignItemKind::Static(ty, _, expr) => { |
1161 | visitor.visit_ty(ty); | |
1162 | visit_opt(expr, |expr| visitor.visit_expr(expr)); | |
1163 | } | |
3c0e092e XL |
1164 | ForeignItemKind::Fn(box Fn { defaultness, generics, sig, body }) => { |
1165 | visit_defaultness(defaultness, visitor); | |
74b04a01 XL |
1166 | visitor.visit_generics(generics); |
1167 | visit_fn_sig(sig, visitor); | |
1168 | visit_opt(body, |body| visitor.visit_block(body)); | |
1169 | } | |
5e7ed085 FG |
1170 | ForeignItemKind::TyAlias(box TyAlias { |
1171 | defaultness, | |
1172 | generics, | |
1173 | where_clauses, | |
1174 | bounds, | |
1175 | ty, | |
1176 | .. | |
1177 | }) => { | |
3c0e092e | 1178 | visit_defaultness(defaultness, visitor); |
9fa01778 | 1179 | visitor.visit_generics(generics); |
5e7ed085 FG |
1180 | visitor.visit_span(&mut where_clauses.0.1); |
1181 | visitor.visit_span(&mut where_clauses.1.1); | |
74b04a01 XL |
1182 | visit_bounds(bounds, visitor); |
1183 | visit_opt(ty, |ty| visitor.visit_ty(ty)); | |
9fa01778 | 1184 | } |
29967ef6 | 1185 | ForeignItemKind::MacCall(mac) => visitor.visit_mac_call(mac), |
9fa01778 | 1186 | } |
9fa01778 | 1187 | visitor.visit_span(span); |
29967ef6 | 1188 | visit_lazy_tts(tokens, visitor); |
9fa01778 XL |
1189 | smallvec![item] |
1190 | } | |
1191 | ||
1192 | pub fn noop_visit_pat<T: MutVisitor>(pat: &mut P<Pat>, vis: &mut T) { | |
29967ef6 | 1193 | let Pat { id, kind, span, tokens } = pat.deref_mut(); |
9fa01778 | 1194 | vis.visit_id(id); |
e74abb32 | 1195 | match kind { |
416331ca | 1196 | PatKind::Wild | PatKind::Rest => {} |
9fa01778 XL |
1197 | PatKind::Ident(_binding_mode, ident, sub) => { |
1198 | vis.visit_ident(ident); | |
1199 | visit_opt(sub, |sub| vis.visit_pat(sub)); | |
1200 | } | |
1201 | PatKind::Lit(e) => vis.visit_expr(e), | |
17df50a5 XL |
1202 | PatKind::TupleStruct(qself, path, elems) => { |
1203 | vis.visit_qself(qself); | |
9fa01778 | 1204 | vis.visit_path(path); |
416331ca | 1205 | visit_vec(elems, |elem| vis.visit_pat(elem)); |
9fa01778 XL |
1206 | } |
1207 | PatKind::Path(qself, path) => { | |
1208 | vis.visit_qself(qself); | |
1209 | vis.visit_path(path); | |
1210 | } | |
17df50a5 XL |
1211 | PatKind::Struct(qself, path, fields, _etc) => { |
1212 | vis.visit_qself(qself); | |
9fa01778 | 1213 | vis.visit_path(path); |
6a06907d | 1214 | fields.flat_map_in_place(|field| vis.flat_map_pat_field(field)); |
e1599b0c | 1215 | } |
9fa01778 XL |
1216 | PatKind::Box(inner) => vis.visit_pat(inner), |
1217 | PatKind::Ref(inner, _mutbl) => vis.visit_pat(inner), | |
1218 | PatKind::Range(e1, e2, Spanned { span: _, node: _ }) => { | |
dfeec247 XL |
1219 | visit_opt(e1, |e| vis.visit_expr(e)); |
1220 | visit_opt(e2, |e| vis.visit_expr(e)); | |
9fa01778 XL |
1221 | vis.visit_span(span); |
1222 | } | |
dfeec247 XL |
1223 | PatKind::Tuple(elems) | PatKind::Slice(elems) | PatKind::Or(elems) => { |
1224 | visit_vec(elems, |elem| vis.visit_pat(elem)) | |
1225 | } | |
9fa01778 | 1226 | PatKind::Paren(inner) => vis.visit_pat(inner), |
29967ef6 | 1227 | PatKind::MacCall(mac) => vis.visit_mac_call(mac), |
9fa01778 XL |
1228 | } |
1229 | vis.visit_span(span); | |
29967ef6 | 1230 | visit_lazy_tts(tokens, vis); |
9fa01778 XL |
1231 | } |
1232 | ||
1233 | pub fn noop_visit_anon_const<T: MutVisitor>(AnonConst { id, value }: &mut AnonConst, vis: &mut T) { | |
1234 | vis.visit_id(id); | |
1235 | vis.visit_expr(value); | |
1236 | } | |
1237 | ||
17df50a5 XL |
1238 | fn noop_visit_inline_asm<T: MutVisitor>(asm: &mut InlineAsm, vis: &mut T) { |
1239 | for (op, _) in &mut asm.operands { | |
1240 | match op { | |
1241 | InlineAsmOperand::In { expr, .. } | |
94222f64 | 1242 | | InlineAsmOperand::Out { expr: Some(expr), .. } |
17df50a5 XL |
1243 | | InlineAsmOperand::InOut { expr, .. } |
1244 | | InlineAsmOperand::Sym { expr, .. } => vis.visit_expr(expr), | |
94222f64 | 1245 | InlineAsmOperand::Out { expr: None, .. } => {} |
17df50a5 XL |
1246 | InlineAsmOperand::SplitInOut { in_expr, out_expr, .. } => { |
1247 | vis.visit_expr(in_expr); | |
1248 | if let Some(out_expr) = out_expr { | |
1249 | vis.visit_expr(out_expr); | |
1250 | } | |
1251 | } | |
1252 | InlineAsmOperand::Const { anon_const, .. } => vis.visit_anon_const(anon_const), | |
1253 | } | |
1254 | } | |
1255 | } | |
1256 | ||
f9f354fc | 1257 | pub fn noop_visit_expr<T: MutVisitor>( |
29967ef6 | 1258 | Expr { kind, id, span, attrs, tokens }: &mut Expr, |
f9f354fc XL |
1259 | vis: &mut T, |
1260 | ) { | |
e74abb32 | 1261 | match kind { |
9fa01778 | 1262 | ExprKind::Box(expr) => vis.visit_expr(expr), |
9fa01778 | 1263 | ExprKind::Array(exprs) => visit_exprs(exprs, vis), |
29967ef6 XL |
1264 | ExprKind::ConstBlock(anon_const) => { |
1265 | vis.visit_anon_const(anon_const); | |
1266 | } | |
9fa01778 XL |
1267 | ExprKind::Repeat(expr, count) => { |
1268 | vis.visit_expr(expr); | |
1269 | vis.visit_anon_const(count); | |
1270 | } | |
1271 | ExprKind::Tup(exprs) => visit_exprs(exprs, vis), | |
1272 | ExprKind::Call(f, args) => { | |
1273 | vis.visit_expr(f); | |
1274 | visit_exprs(args, vis); | |
1275 | } | |
f035d41b | 1276 | ExprKind::MethodCall(PathSegment { ident, id, args }, exprs, span) => { |
9fa01778 XL |
1277 | vis.visit_ident(ident); |
1278 | vis.visit_id(id); | |
1279 | visit_opt(args, |args| vis.visit_generic_args(args)); | |
1280 | visit_exprs(exprs, vis); | |
f035d41b | 1281 | vis.visit_span(span); |
9fa01778 XL |
1282 | } |
1283 | ExprKind::Binary(_binop, lhs, rhs) => { | |
1284 | vis.visit_expr(lhs); | |
1285 | vis.visit_expr(rhs); | |
1286 | } | |
1287 | ExprKind::Unary(_unop, ohs) => vis.visit_expr(ohs), | |
9fa01778 XL |
1288 | ExprKind::Cast(expr, ty) => { |
1289 | vis.visit_expr(expr); | |
1290 | vis.visit_ty(ty); | |
1291 | } | |
1292 | ExprKind::Type(expr, ty) => { | |
1293 | vis.visit_expr(expr); | |
1294 | vis.visit_ty(ty); | |
1295 | } | |
60c5eb7d | 1296 | ExprKind::AddrOf(_, _, ohs) => vis.visit_expr(ohs), |
94222f64 | 1297 | ExprKind::Let(pat, scrutinee, _) => { |
e1599b0c | 1298 | vis.visit_pat(pat); |
dc9dc135 XL |
1299 | vis.visit_expr(scrutinee); |
1300 | } | |
9fa01778 XL |
1301 | ExprKind::If(cond, tr, fl) => { |
1302 | vis.visit_expr(cond); | |
1303 | vis.visit_block(tr); | |
1304 | visit_opt(fl, |fl| vis.visit_expr(fl)); | |
1305 | } | |
9fa01778 XL |
1306 | ExprKind::While(cond, body, label) => { |
1307 | vis.visit_expr(cond); | |
1308 | vis.visit_block(body); | |
1309 | visit_opt(label, |label| vis.visit_label(label)); | |
1310 | } | |
9fa01778 XL |
1311 | ExprKind::ForLoop(pat, iter, body, label) => { |
1312 | vis.visit_pat(pat); | |
1313 | vis.visit_expr(iter); | |
1314 | vis.visit_block(body); | |
1315 | visit_opt(label, |label| vis.visit_label(label)); | |
1316 | } | |
1317 | ExprKind::Loop(body, label) => { | |
1318 | vis.visit_block(body); | |
1319 | visit_opt(label, |label| vis.visit_label(label)); | |
1320 | } | |
1321 | ExprKind::Match(expr, arms) => { | |
1322 | vis.visit_expr(expr); | |
e1599b0c | 1323 | arms.flat_map_in_place(|arm| vis.flat_map_arm(arm)); |
9fa01778 XL |
1324 | } |
1325 | ExprKind::Closure(_capture_by, asyncness, _movability, decl, body, span) => { | |
1326 | vis.visit_asyncness(asyncness); | |
1327 | vis.visit_fn_decl(decl); | |
1328 | vis.visit_expr(body); | |
1329 | vis.visit_span(span); | |
1330 | } | |
1331 | ExprKind::Block(blk, label) => { | |
1332 | vis.visit_block(blk); | |
1333 | visit_opt(label, |label| vis.visit_label(label)); | |
1334 | } | |
1335 | ExprKind::Async(_capture_by, node_id, body) => { | |
1336 | vis.visit_id(node_id); | |
1337 | vis.visit_block(body); | |
1338 | } | |
416331ca | 1339 | ExprKind::Await(expr) => vis.visit_expr(expr), |
dfeec247 | 1340 | ExprKind::Assign(el, er, _) => { |
9fa01778 XL |
1341 | vis.visit_expr(el); |
1342 | vis.visit_expr(er); | |
1343 | } | |
1344 | ExprKind::AssignOp(_op, el, er) => { | |
1345 | vis.visit_expr(el); | |
1346 | vis.visit_expr(er); | |
1347 | } | |
1348 | ExprKind::Field(el, ident) => { | |
1349 | vis.visit_expr(el); | |
1350 | vis.visit_ident(ident); | |
1351 | } | |
1352 | ExprKind::Index(el, er) => { | |
1353 | vis.visit_expr(el); | |
1354 | vis.visit_expr(er); | |
1355 | } | |
1356 | ExprKind::Range(e1, e2, _lim) => { | |
1357 | visit_opt(e1, |e1| vis.visit_expr(e1)); | |
1358 | visit_opt(e2, |e2| vis.visit_expr(e2)); | |
1359 | } | |
fc512014 | 1360 | ExprKind::Underscore => {} |
9fa01778 XL |
1361 | ExprKind::Path(qself, path) => { |
1362 | vis.visit_qself(qself); | |
1363 | vis.visit_path(path); | |
1364 | } | |
1365 | ExprKind::Break(label, expr) => { | |
1366 | visit_opt(label, |label| vis.visit_label(label)); | |
1367 | visit_opt(expr, |expr| vis.visit_expr(expr)); | |
1368 | } | |
1369 | ExprKind::Continue(label) => { | |
1370 | visit_opt(label, |label| vis.visit_label(label)); | |
1371 | } | |
1372 | ExprKind::Ret(expr) => { | |
1373 | visit_opt(expr, |expr| vis.visit_expr(expr)); | |
1374 | } | |
17df50a5 | 1375 | ExprKind::InlineAsm(asm) => noop_visit_inline_asm(asm, vis), |
29967ef6 | 1376 | ExprKind::MacCall(mac) => vis.visit_mac_call(mac), |
6a06907d | 1377 | ExprKind::Struct(se) => { |
17df50a5 XL |
1378 | let StructExpr { qself, path, fields, rest } = se.deref_mut(); |
1379 | vis.visit_qself(qself); | |
9fa01778 | 1380 | vis.visit_path(path); |
6a06907d XL |
1381 | fields.flat_map_in_place(|field| vis.flat_map_expr_field(field)); |
1382 | match rest { | |
29967ef6 XL |
1383 | StructRest::Base(expr) => vis.visit_expr(expr), |
1384 | StructRest::Rest(_span) => {} | |
1385 | StructRest::None => {} | |
1386 | } | |
dfeec247 | 1387 | } |
9fa01778 XL |
1388 | ExprKind::Paren(expr) => { |
1389 | vis.visit_expr(expr); | |
9fa01778 XL |
1390 | } |
1391 | ExprKind::Yield(expr) => { | |
1392 | visit_opt(expr, |expr| vis.visit_expr(expr)); | |
1393 | } | |
1394 | ExprKind::Try(expr) => vis.visit_expr(expr), | |
1395 | ExprKind::TryBlock(body) => vis.visit_block(body), | |
dc9dc135 | 1396 | ExprKind::Lit(_) | ExprKind::Err => {} |
9fa01778 XL |
1397 | } |
1398 | vis.visit_id(id); | |
1399 | vis.visit_span(span); | |
1400 | visit_thin_attrs(attrs, vis); | |
29967ef6 | 1401 | visit_lazy_tts(tokens, vis); |
9fa01778 XL |
1402 | } |
1403 | ||
1404 | pub fn noop_filter_map_expr<T: MutVisitor>(mut e: P<Expr>, vis: &mut T) -> Option<P<Expr>> { | |
dfeec247 XL |
1405 | Some({ |
1406 | vis.visit_expr(&mut e); | |
1407 | e | |
1408 | }) | |
9fa01778 XL |
1409 | } |
1410 | ||
dfeec247 | 1411 | pub fn noop_flat_map_stmt<T: MutVisitor>( |
fc512014 | 1412 | Stmt { kind, mut span, mut id }: Stmt, |
dfeec247 XL |
1413 | vis: &mut T, |
1414 | ) -> SmallVec<[Stmt; 1]> { | |
9fa01778 XL |
1415 | vis.visit_id(&mut id); |
1416 | vis.visit_span(&mut span); | |
94222f64 XL |
1417 | let stmts: SmallVec<_> = noop_flat_map_stmt_kind(kind, vis) |
1418 | .into_iter() | |
1419 | .map(|kind| Stmt { id, kind, span }) | |
1420 | .collect(); | |
1421 | if stmts.len() > 1 { | |
1422 | panic!( | |
1423 | "cloning statement `NodeId`s is prohibited by default, \ | |
1424 | the visitor should implement custom statement visiting" | |
1425 | ); | |
1426 | } | |
1427 | stmts | |
9fa01778 XL |
1428 | } |
1429 | ||
dfeec247 XL |
1430 | pub fn noop_flat_map_stmt_kind<T: MutVisitor>( |
1431 | kind: StmtKind, | |
1432 | vis: &mut T, | |
1433 | ) -> SmallVec<[StmtKind; 1]> { | |
e74abb32 | 1434 | match kind { |
dfeec247 XL |
1435 | StmtKind::Local(mut local) => smallvec![StmtKind::Local({ |
1436 | vis.visit_local(&mut local); | |
1437 | local | |
1438 | })], | |
9fa01778 | 1439 | StmtKind::Item(item) => vis.flat_map_item(item).into_iter().map(StmtKind::Item).collect(), |
dfeec247 XL |
1440 | StmtKind::Expr(expr) => vis.filter_map_expr(expr).into_iter().map(StmtKind::Expr).collect(), |
1441 | StmtKind::Semi(expr) => vis.filter_map_expr(expr).into_iter().map(StmtKind::Semi).collect(), | |
74b04a01 | 1442 | StmtKind::Empty => smallvec![StmtKind::Empty], |
ba9703b0 | 1443 | StmtKind::MacCall(mut mac) => { |
fc512014 | 1444 | let MacCallStmt { mac: mac_, style: _, attrs, tokens } = mac.deref_mut(); |
29967ef6 | 1445 | vis.visit_mac_call(mac_); |
9fa01778 | 1446 | visit_thin_attrs(attrs, vis); |
fc512014 | 1447 | visit_lazy_tts(tokens, vis); |
ba9703b0 | 1448 | smallvec![StmtKind::MacCall(mac)] |
9fa01778 XL |
1449 | } |
1450 | } | |
1451 | } | |
1452 | ||
1b1a35ee XL |
1453 | pub fn noop_visit_vis<T: MutVisitor>(visibility: &mut Visibility, vis: &mut T) { |
1454 | match &mut visibility.kind { | |
9fa01778 XL |
1455 | VisibilityKind::Public | VisibilityKind::Crate(_) | VisibilityKind::Inherited => {} |
1456 | VisibilityKind::Restricted { path, id } => { | |
1457 | vis.visit_path(path); | |
1458 | vis.visit_id(id); | |
1459 | } | |
1460 | } | |
1b1a35ee | 1461 | vis.visit_span(&mut visibility.span); |
9fa01778 | 1462 | } |
a2a8927a XL |
1463 | |
1464 | /// Some value for the AST node that is valid but possibly meaningless. | |
1465 | pub trait DummyAstNode { | |
1466 | fn dummy() -> Self; | |
1467 | } | |
1468 | ||
1469 | impl<T> DummyAstNode for Option<T> { | |
1470 | fn dummy() -> Self { | |
1471 | Default::default() | |
1472 | } | |
1473 | } | |
1474 | ||
1475 | impl<T: DummyAstNode + 'static> DummyAstNode for P<T> { | |
1476 | fn dummy() -> Self { | |
1477 | P(DummyAstNode::dummy()) | |
1478 | } | |
1479 | } | |
1480 | ||
1481 | impl<T> DummyAstNode for ThinVec<T> { | |
1482 | fn dummy() -> Self { | |
1483 | Default::default() | |
1484 | } | |
1485 | } | |
1486 | ||
1487 | impl DummyAstNode for Item { | |
1488 | fn dummy() -> Self { | |
1489 | Item { | |
1490 | attrs: Default::default(), | |
1491 | id: DUMMY_NODE_ID, | |
1492 | span: Default::default(), | |
1493 | vis: Visibility { | |
1494 | kind: VisibilityKind::Public, | |
1495 | span: Default::default(), | |
1496 | tokens: Default::default(), | |
1497 | }, | |
1498 | ident: Ident::empty(), | |
1499 | kind: ItemKind::ExternCrate(None), | |
1500 | tokens: Default::default(), | |
1501 | } | |
1502 | } | |
1503 | } | |
1504 | ||
1505 | impl DummyAstNode for Expr { | |
1506 | fn dummy() -> Self { | |
1507 | Expr { | |
1508 | id: DUMMY_NODE_ID, | |
1509 | kind: ExprKind::Err, | |
1510 | span: Default::default(), | |
1511 | attrs: Default::default(), | |
1512 | tokens: Default::default(), | |
1513 | } | |
1514 | } | |
1515 | } | |
1516 | ||
1517 | impl DummyAstNode for Ty { | |
1518 | fn dummy() -> Self { | |
1519 | Ty { | |
1520 | id: DUMMY_NODE_ID, | |
1521 | kind: TyKind::Err, | |
1522 | span: Default::default(), | |
1523 | tokens: Default::default(), | |
1524 | } | |
1525 | } | |
1526 | } | |
1527 | ||
1528 | impl DummyAstNode for Pat { | |
1529 | fn dummy() -> Self { | |
1530 | Pat { | |
1531 | id: DUMMY_NODE_ID, | |
1532 | kind: PatKind::Wild, | |
1533 | span: Default::default(), | |
1534 | tokens: Default::default(), | |
1535 | } | |
1536 | } | |
1537 | } | |
1538 | ||
1539 | impl DummyAstNode for Stmt { | |
1540 | fn dummy() -> Self { | |
1541 | Stmt { id: DUMMY_NODE_ID, kind: StmtKind::Empty, span: Default::default() } | |
1542 | } | |
1543 | } | |
1544 | ||
1545 | impl DummyAstNode for Block { | |
1546 | fn dummy() -> Self { | |
1547 | Block { | |
1548 | stmts: Default::default(), | |
1549 | id: DUMMY_NODE_ID, | |
1550 | rules: BlockCheckMode::Default, | |
1551 | span: Default::default(), | |
1552 | tokens: Default::default(), | |
1553 | could_be_bare_literal: Default::default(), | |
1554 | } | |
1555 | } | |
1556 | } | |
1557 | ||
1558 | impl DummyAstNode for Crate { | |
1559 | fn dummy() -> Self { | |
1560 | Crate { | |
1561 | attrs: Default::default(), | |
1562 | items: Default::default(), | |
5e7ed085 | 1563 | spans: Default::default(), |
a2a8927a XL |
1564 | id: DUMMY_NODE_ID, |
1565 | is_placeholder: Default::default(), | |
1566 | } | |
1567 | } | |
1568 | } |