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