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.
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.
12 use crate::token
::{self, Token}
;
13 use crate::tokenstream
::*;
15 use rustc_data_structures
::map_in_place
::MapInPlace
;
16 use rustc_data_structures
::sync
::Lrc
;
17 use rustc_data_structures
::thin_vec
::ThinVec
;
18 use rustc_span
::source_map
::Spanned
;
19 use rustc_span
::symbol
::Ident
;
22 use smallvec
::{smallvec, Array, SmallVec}
;
23 use std
::ops
::DerefMut
;
24 use std
::{panic, ptr}
;
26 pub trait ExpectOne
<A
: Array
> {
27 fn expect_one(self, err
: &'
static str) -> A
::Item
;
30 impl<A
: Array
> ExpectOne
<A
> for SmallVec
<A
> {
31 fn expect_one(self, err
: &'
static str) -> A
::Item
{
32 assert
!(self.len() == 1, "{}", err
);
33 self.into_iter().next().unwrap()
37 pub trait MutVisitor
: Sized
{
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.
41 const VISIT_TOKENS
: bool
= false;
43 // Methods in this trait have one of three forms:
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
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
55 // When writing these methods, it is better to use destructuring like this:
57 // fn visit_abc(&mut self, ABC { a, b, c: _ }: &mut ABC) {
62 // than to use field access like this:
64 // fn visit_abc(&mut self, abc: &mut ABC) {
65 // visit_a(&mut abc.a);
66 // visit_b(&mut abc.b);
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.
76 fn visit_crate(&mut self, c
: &mut Crate
) {
77 noop_visit_crate(c
, self)
80 fn visit_meta_list_item(&mut self, list_item
: &mut NestedMetaItem
) {
81 noop_visit_meta_list_item(list_item
, self);
84 fn visit_meta_item(&mut self, meta_item
: &mut MetaItem
) {
85 noop_visit_meta_item(meta_item
, self);
88 fn visit_use_tree(&mut self, use_tree
: &mut UseTree
) {
89 noop_visit_use_tree(use_tree
, self);
92 fn flat_map_foreign_item(&mut self, ni
: P
<ForeignItem
>) -> SmallVec
<[P
<ForeignItem
>; 1]> {
93 noop_flat_map_foreign_item(ni
, self)
96 fn flat_map_item(&mut self, i
: P
<Item
>) -> SmallVec
<[P
<Item
>; 1]> {
97 noop_flat_map_item(i
, self)
100 fn visit_fn_header(&mut self, header
: &mut FnHeader
) {
101 noop_visit_fn_header(header
, self);
104 fn flat_map_field_def(&mut self, fd
: FieldDef
) -> SmallVec
<[FieldDef
; 1]> {
105 noop_flat_map_field_def(fd
, self)
108 fn visit_item_kind(&mut self, i
: &mut ItemKind
) {
109 noop_visit_item_kind(i
, self);
112 fn flat_map_trait_item(&mut self, i
: P
<AssocItem
>) -> SmallVec
<[P
<AssocItem
>; 1]> {
113 noop_flat_map_assoc_item(i
, self)
116 fn flat_map_impl_item(&mut self, i
: P
<AssocItem
>) -> SmallVec
<[P
<AssocItem
>; 1]> {
117 noop_flat_map_assoc_item(i
, self)
120 fn visit_fn_decl(&mut self, d
: &mut P
<FnDecl
>) {
121 noop_visit_fn_decl(d
, self);
124 fn visit_asyncness(&mut self, a
: &mut Async
) {
125 noop_visit_asyncness(a
, self);
128 fn visit_block(&mut self, b
: &mut P
<Block
>) {
129 noop_visit_block(b
, self);
132 fn flat_map_stmt(&mut self, s
: Stmt
) -> SmallVec
<[Stmt
; 1]> {
133 noop_flat_map_stmt(s
, self)
136 fn flat_map_arm(&mut self, arm
: Arm
) -> SmallVec
<[Arm
; 1]> {
137 noop_flat_map_arm(arm
, self)
140 fn visit_pat(&mut self, p
: &mut P
<Pat
>) {
141 noop_visit_pat(p
, self);
144 fn visit_anon_const(&mut self, c
: &mut AnonConst
) {
145 noop_visit_anon_const(c
, self);
148 fn visit_expr(&mut self, e
: &mut P
<Expr
>) {
149 noop_visit_expr(e
, self);
152 fn filter_map_expr(&mut self, e
: P
<Expr
>) -> Option
<P
<Expr
>> {
153 noop_filter_map_expr(e
, self)
156 fn visit_generic_arg(&mut self, arg
: &mut GenericArg
) {
157 noop_visit_generic_arg(arg
, self);
160 fn visit_ty(&mut self, t
: &mut P
<Ty
>) {
161 noop_visit_ty(t
, self);
164 fn visit_lifetime(&mut self, l
: &mut Lifetime
) {
165 noop_visit_lifetime(l
, self);
168 fn visit_constraint(&mut self, t
: &mut AssocConstraint
) {
169 noop_visit_constraint(t
, self);
172 fn visit_foreign_mod(&mut self, nm
: &mut ForeignMod
) {
173 noop_visit_foreign_mod(nm
, self);
176 fn flat_map_variant(&mut self, v
: Variant
) -> SmallVec
<[Variant
; 1]> {
177 noop_flat_map_variant(v
, self)
180 fn visit_ident(&mut self, i
: &mut Ident
) {
181 noop_visit_ident(i
, self);
184 fn visit_path(&mut self, p
: &mut Path
) {
185 noop_visit_path(p
, self);
188 fn visit_qself(&mut self, qs
: &mut Option
<QSelf
>) {
189 noop_visit_qself(qs
, self);
192 fn visit_generic_args(&mut self, p
: &mut GenericArgs
) {
193 noop_visit_generic_args(p
, self);
196 fn visit_angle_bracketed_parameter_data(&mut self, p
: &mut AngleBracketedArgs
) {
197 noop_visit_angle_bracketed_parameter_data(p
, self);
200 fn visit_parenthesized_parameter_data(&mut self, p
: &mut ParenthesizedArgs
) {
201 noop_visit_parenthesized_parameter_data(p
, self);
204 fn visit_local(&mut self, l
: &mut P
<Local
>) {
205 noop_visit_local(l
, self);
208 fn visit_mac_call(&mut self, mac
: &mut MacCall
) {
209 noop_visit_mac(mac
, self);
212 fn visit_macro_def(&mut self, def
: &mut MacroDef
) {
213 noop_visit_macro_def(def
, self);
216 fn visit_label(&mut self, label
: &mut Label
) {
217 noop_visit_label(label
, self);
220 fn visit_attribute(&mut self, at
: &mut Attribute
) {
221 noop_visit_attribute(at
, self);
224 fn flat_map_param(&mut self, param
: Param
) -> SmallVec
<[Param
; 1]> {
225 noop_flat_map_param(param
, self)
228 fn visit_generics(&mut self, generics
: &mut Generics
) {
229 noop_visit_generics(generics
, self);
232 fn visit_trait_ref(&mut self, tr
: &mut TraitRef
) {
233 noop_visit_trait_ref(tr
, self);
236 fn visit_poly_trait_ref(&mut self, p
: &mut PolyTraitRef
) {
237 noop_visit_poly_trait_ref(p
, self);
240 fn visit_variant_data(&mut self, vdata
: &mut VariantData
) {
241 noop_visit_variant_data(vdata
, self);
244 fn flat_map_generic_param(&mut self, param
: GenericParam
) -> SmallVec
<[GenericParam
; 1]> {
245 noop_flat_map_generic_param(param
, self)
248 fn visit_param_bound(&mut self, tpb
: &mut GenericBound
) {
249 noop_visit_param_bound(tpb
, self);
252 fn visit_mt(&mut self, mt
: &mut MutTy
) {
253 noop_visit_mt(mt
, self);
256 fn flat_map_expr_field(&mut self, f
: ExprField
) -> SmallVec
<[ExprField
; 1]> {
257 noop_flat_map_expr_field(f
, self)
260 fn visit_where_clause(&mut self, where_clause
: &mut WhereClause
) {
261 noop_visit_where_clause(where_clause
, self);
264 fn visit_where_predicate(&mut self, where_predicate
: &mut WherePredicate
) {
265 noop_visit_where_predicate(where_predicate
, self);
268 fn visit_vis(&mut self, vis
: &mut Visibility
) {
269 noop_visit_vis(vis
, self);
272 fn visit_id(&mut self, _id
: &mut NodeId
) {
276 fn visit_span(&mut self, _sp
: &mut Span
) {
280 fn flat_map_pat_field(&mut self, fp
: PatField
) -> SmallVec
<[PatField
; 1]> {
281 noop_flat_map_pat_field(fp
, self)
284 fn visit_inline_asm(&mut self, asm
: &mut InlineAsm
) {
285 noop_visit_inline_asm(asm
, self)
288 fn visit_inline_asm_sym(&mut self, sym
: &mut InlineAsmSym
) {
289 noop_visit_inline_asm_sym(sym
, self)
293 /// Use a map-style function (`FnOnce(T) -> T`) to overwrite a `&mut T`. Useful
294 /// when using a `flat_map_*` or `filter_map_*` method within a `visit_`
297 // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
298 pub fn visit_clobber
<T
: DummyAstNode
>(t
: &mut T
, f
: impl FnOnce(T
) -> T
) {
300 // Safe because `t` is used in a read-only fashion by `read()` before
301 // being overwritten by `write()`.
302 let old_t
= ptr
::read(t
);
304 panic
::catch_unwind(panic
::AssertUnwindSafe(|| f(old_t
))).unwrap_or_else(|err
| {
305 // Set `t` to some valid but possible meaningless value,
306 // and pass the fatal error further.
307 ptr
::write(t
, T
::dummy());
308 panic
::resume_unwind(err
);
310 ptr
::write(t
, new_t
);
314 // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
316 pub fn visit_vec
<T
, F
>(elems
: &mut Vec
<T
>, mut visit_elem
: F
)
325 // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
327 pub fn visit_opt
<T
, F
>(opt
: &mut Option
<T
>, mut visit_elem
: F
)
331 if let Some(elem
) = opt
{
336 // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
337 pub fn visit_attrs
<T
: MutVisitor
>(attrs
: &mut Vec
<Attribute
>, vis
: &mut T
) {
338 visit_vec(attrs
, |attr
| vis
.visit_attribute(attr
));
341 // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
342 pub fn visit_thin_attrs
<T
: MutVisitor
>(attrs
: &mut AttrVec
, vis
: &mut T
) {
343 for attr
in attrs
.iter_mut() {
344 vis
.visit_attribute(attr
);
348 // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
349 pub fn visit_exprs
<T
: MutVisitor
>(exprs
: &mut Vec
<P
<Expr
>>, vis
: &mut T
) {
350 exprs
.flat_map_in_place(|expr
| vis
.filter_map_expr(expr
))
353 // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
354 pub fn visit_bounds
<T
: MutVisitor
>(bounds
: &mut GenericBounds
, vis
: &mut T
) {
355 visit_vec(bounds
, |bound
| vis
.visit_param_bound(bound
));
358 // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
359 pub fn visit_fn_sig
<T
: MutVisitor
>(FnSig { header, decl, span }
: &mut FnSig
, vis
: &mut T
) {
360 vis
.visit_fn_header(header
);
361 vis
.visit_fn_decl(decl
);
362 vis
.visit_span(span
);
365 // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
366 pub fn visit_mac_args
<T
: MutVisitor
>(args
: &mut MacArgs
, vis
: &mut T
) {
369 MacArgs
::Delimited(dspan
, _delim
, tokens
) => {
370 visit_delim_span(dspan
, vis
);
371 visit_tts(tokens
, vis
);
373 MacArgs
::Eq(eq_span
, MacArgsEq
::Ast(expr
)) => {
374 vis
.visit_span(eq_span
);
375 vis
.visit_expr(expr
);
377 MacArgs
::Eq(_
, MacArgsEq
::Hir(lit
)) => {
378 unreachable
!("in literal form when visiting mac args eq: {:?}", lit
)
383 pub fn visit_delim_span
<T
: MutVisitor
>(dspan
: &mut DelimSpan
, vis
: &mut T
) {
384 vis
.visit_span(&mut dspan
.open
);
385 vis
.visit_span(&mut dspan
.close
);
388 pub fn noop_flat_map_pat_field
<T
: MutVisitor
>(
391 ) -> SmallVec
<[PatField
; 1]> {
392 let PatField { attrs, id, ident, is_placeholder: _, is_shorthand: _, pat, span }
= &mut fp
;
394 vis
.visit_ident(ident
);
396 vis
.visit_span(span
);
397 visit_thin_attrs(attrs
, vis
);
401 pub fn noop_visit_use_tree
<T
: MutVisitor
>(use_tree
: &mut UseTree
, vis
: &mut T
) {
402 let UseTree { prefix, kind, span }
= use_tree
;
403 vis
.visit_path(prefix
);
405 UseTreeKind
::Simple(rename
, id1
, id2
) => {
406 visit_opt(rename
, |rename
| vis
.visit_ident(rename
));
410 UseTreeKind
::Nested(items
) => {
411 for (tree
, id
) in items
{
412 vis
.visit_use_tree(tree
);
416 UseTreeKind
::Glob
=> {}
418 vis
.visit_span(span
);
421 pub fn noop_flat_map_arm
<T
: MutVisitor
>(mut arm
: Arm
, vis
: &mut T
) -> SmallVec
<[Arm
; 1]> {
422 let Arm { attrs, pat, guard, body, span, id, is_placeholder: _ }
= &mut arm
;
423 visit_thin_attrs(attrs
, vis
);
426 visit_opt(guard
, |guard
| vis
.visit_expr(guard
));
427 vis
.visit_expr(body
);
428 vis
.visit_span(span
);
432 pub fn noop_visit_constraint
<T
: MutVisitor
>(
433 AssocConstraint { id, ident, gen_args, kind, span }
: &mut AssocConstraint
,
437 vis
.visit_ident(ident
);
438 if let Some(ref mut gen_args
) = gen_args
{
439 vis
.visit_generic_args(gen_args
);
442 AssocConstraintKind
::Equality { ref mut term }
=> match term
{
443 Term
::Ty(ty
) => vis
.visit_ty(ty
),
444 Term
::Const(c
) => vis
.visit_anon_const(c
),
446 AssocConstraintKind
::Bound { ref mut bounds }
=> visit_bounds(bounds
, vis
),
448 vis
.visit_span(span
);
451 pub fn noop_visit_ty
<T
: MutVisitor
>(ty
: &mut P
<Ty
>, vis
: &mut T
) {
452 let Ty { id, kind, span, tokens }
= ty
.deref_mut();
455 TyKind
::Infer
| TyKind
::ImplicitSelf
| TyKind
::Err
| TyKind
::Never
| TyKind
::CVarArgs
=> {}
456 TyKind
::Slice(ty
) => vis
.visit_ty(ty
),
457 TyKind
::Ptr(mt
) => vis
.visit_mt(mt
),
458 TyKind
::Rptr(lt
, mt
) => {
459 visit_opt(lt
, |lt
| noop_visit_lifetime(lt
, vis
));
462 TyKind
::BareFn(bft
) => {
463 let BareFnTy { unsafety, ext: _, generic_params, decl, decl_span }
= bft
.deref_mut();
464 visit_unsafety(unsafety
, vis
);
465 generic_params
.flat_map_in_place(|param
| vis
.flat_map_generic_param(param
));
466 vis
.visit_fn_decl(decl
);
467 vis
.visit_span(decl_span
);
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
);
475 TyKind
::Array(ty
, length
) => {
477 vis
.visit_anon_const(length
);
479 TyKind
::Typeof(expr
) => vis
.visit_anon_const(expr
),
480 TyKind
::TraitObject(bounds
, _syntax
) => {
481 visit_vec(bounds
, |bound
| vis
.visit_param_bound(bound
))
483 TyKind
::ImplTrait(id
, bounds
) => {
485 visit_vec(bounds
, |bound
| vis
.visit_param_bound(bound
));
487 TyKind
::MacCall(mac
) => vis
.visit_mac_call(mac
),
489 vis
.visit_span(span
);
490 visit_lazy_tts(tokens
, vis
);
493 pub fn noop_visit_foreign_mod
<T
: MutVisitor
>(foreign_mod
: &mut ForeignMod
, vis
: &mut T
) {
494 let ForeignMod { unsafety, abi: _, items }
= foreign_mod
;
495 visit_unsafety(unsafety
, vis
);
496 items
.flat_map_in_place(|item
| vis
.flat_map_foreign_item(item
));
499 pub fn noop_flat_map_variant
<T
: MutVisitor
>(
500 mut variant
: Variant
,
502 ) -> SmallVec
<[Variant
; 1]> {
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
);
506 visit_thin_attrs(attrs
, visitor
);
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
);
514 pub fn noop_visit_ident
<T
: MutVisitor
>(Ident { name: _, span }
: &mut Ident
, vis
: &mut T
) {
515 vis
.visit_span(span
);
518 pub fn noop_visit_path
<T
: MutVisitor
>(Path { segments, span, tokens }
: &mut Path
, vis
: &mut T
) {
519 vis
.visit_span(span
);
520 for PathSegment { ident, id, args }
in segments
{
521 vis
.visit_ident(ident
);
523 visit_opt(args
, |args
| vis
.visit_generic_args(args
));
525 visit_lazy_tts(tokens
, vis
);
528 pub fn noop_visit_qself
<T
: MutVisitor
>(qself
: &mut Option
<QSelf
>, vis
: &mut T
) {
529 visit_opt(qself
, |QSelf { ty, path_span, position: _ }
| {
531 vis
.visit_span(path_span
);
535 pub fn noop_visit_generic_args
<T
: MutVisitor
>(generic_args
: &mut GenericArgs
, vis
: &mut T
) {
537 GenericArgs
::AngleBracketed(data
) => vis
.visit_angle_bracketed_parameter_data(data
),
538 GenericArgs
::Parenthesized(data
) => vis
.visit_parenthesized_parameter_data(data
),
542 pub fn noop_visit_generic_arg
<T
: MutVisitor
>(arg
: &mut GenericArg
, vis
: &mut T
) {
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
),
550 pub fn noop_visit_angle_bracketed_parameter_data
<T
: MutVisitor
>(
551 data
: &mut AngleBracketedArgs
,
554 let AngleBracketedArgs { args, span }
= data
;
555 visit_vec(args
, |arg
| match arg
{
556 AngleBracketedArg
::Arg(arg
) => vis
.visit_generic_arg(arg
),
557 AngleBracketedArg
::Constraint(constraint
) => vis
.visit_constraint(constraint
),
559 vis
.visit_span(span
);
562 pub fn noop_visit_parenthesized_parameter_data
<T
: MutVisitor
>(
563 args
: &mut ParenthesizedArgs
,
566 let ParenthesizedArgs { inputs, output, span, .. }
= args
;
567 visit_vec(inputs
, |input
| vis
.visit_ty(input
));
568 noop_visit_fn_ret_ty(output
, vis
);
569 vis
.visit_span(span
);
572 pub fn noop_visit_local
<T
: MutVisitor
>(local
: &mut P
<Local
>, vis
: &mut T
) {
573 let Local { id, pat, ty, kind, span, attrs, tokens }
= local
.deref_mut();
576 visit_opt(ty
, |ty
| vis
.visit_ty(ty
));
578 LocalKind
::Decl
=> {}
579 LocalKind
::Init(init
) => {
580 vis
.visit_expr(init
);
582 LocalKind
::InitElse(init
, els
) => {
583 vis
.visit_expr(init
);
584 vis
.visit_block(els
);
587 vis
.visit_span(span
);
588 visit_thin_attrs(attrs
, vis
);
589 visit_lazy_tts(tokens
, vis
);
592 pub fn noop_visit_attribute
<T
: MutVisitor
>(attr
: &mut Attribute
, vis
: &mut T
) {
593 let Attribute { kind, id: _, style: _, span }
= attr
;
595 AttrKind
::Normal(AttrItem { path, args, tokens }
, attr_tokens
) => {
596 vis
.visit_path(path
);
597 visit_mac_args(args
, vis
);
598 visit_lazy_tts(tokens
, vis
);
599 visit_lazy_tts(attr_tokens
, vis
);
601 AttrKind
::DocComment(..) => {}
603 vis
.visit_span(span
);
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
);
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
);
617 pub fn noop_visit_meta_list_item
<T
: MutVisitor
>(li
: &mut NestedMetaItem
, vis
: &mut T
) {
619 NestedMetaItem
::MetaItem(mi
) => vis
.visit_meta_item(mi
),
620 NestedMetaItem
::Literal(_lit
) => {}
624 pub fn noop_visit_meta_item
<T
: MutVisitor
>(mi
: &mut MetaItem
, vis
: &mut T
) {
625 let MetaItem { path: _, kind, span }
= mi
;
627 MetaItemKind
::Word
=> {}
628 MetaItemKind
::List(mis
) => visit_vec(mis
, |mi
| vis
.visit_meta_list_item(mi
)),
629 MetaItemKind
::NameValue(_s
) => {}
631 vis
.visit_span(span
);
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
;
637 visit_thin_attrs(attrs
, vis
);
639 vis
.visit_span(span
);
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
) {
647 AttrAnnotatedTokenTree
::Token(token
) => {
648 visit_token(token
, vis
);
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
);
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
);
661 AttrKind
::DocComment(..) => {
662 vis
.visit_span(&mut attr
.span
);
666 visit_lazy_tts_opt_mut(Some(&mut data
.tokens
), vis
);
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
) {
674 TokenTree
::Token(token
) => {
675 visit_token(token
, vis
);
677 TokenTree
::Delimited(DelimSpan { open, close }
, _delim
, tts
) => {
678 vis
.visit_span(open
);
679 vis
.visit_span(close
);
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
, _is_joint
)| visit_tt(tree
, vis
));
693 pub fn visit_attr_annotated_tts
<T
: MutVisitor
>(
694 AttrAnnotatedTokenStream(tts
): &mut AttrAnnotatedTokenStream
,
697 if T
::VISIT_TOKENS
&& !tts
.is_empty() {
698 let tts
= Lrc
::make_mut(tts
);
699 visit_vec(tts
, |(tree
, _is_joint
)| visit_attr_annotated_tt(tree
, vis
));
703 pub fn visit_lazy_tts_opt_mut
<T
: MutVisitor
>(lazy_tts
: Option
<&mut LazyTokenStream
>, vis
: &mut T
) {
705 if let Some(lazy_tts
) = lazy_tts
{
706 let mut tts
= lazy_tts
.create_token_stream();
707 visit_attr_annotated_tts(&mut tts
, vis
);
708 *lazy_tts
= LazyTokenStream
::new(tts
);
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
);
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
;
724 token
::Ident(name
, _
) | token
::Lifetime(name
) => {
725 let mut ident
= Ident
::new(*name
, *span
);
726 vis
.visit_ident(&mut ident
);
729 return; // Avoid visiting the span for the second time.
731 token
::Interpolated(nt
) => {
732 let mut nt
= Lrc
::make_mut(nt
);
733 visit_nonterminal(&mut nt
, vis
);
737 vis
.visit_span(span
);
740 // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
741 /// Applies the visitor to elements of interpolated nodes.
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.
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
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
) {
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")
772 token
::NtBlock(block
) => vis
.visit_block(block
),
773 token
::NtStmt(stmt
) => visit_clobber(stmt
, |stmt
| {
774 // See reasoning above.
776 vis
.flat_map_stmt(stmt
).expect_one("expected visitor to produce exactly one item")
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
);
791 token
::NtPath(path
) => vis
.visit_path(path
),
792 token
::NtVis(visib
) => vis
.visit_vis(visib
),
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
) {
799 Defaultness
::Default(span
) => vis
.visit_span(span
),
800 Defaultness
::Final
=> {}
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
) {
807 Unsafe
::Yes(span
) => vis
.visit_span(span
),
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
) {
815 ImplPolarity
::Positive
=> {}
816 ImplPolarity
::Negative(span
) => vis
.visit_span(span
),
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
) {
823 Const
::Yes(span
) => vis
.visit_span(span
),
828 pub fn noop_visit_asyncness
<T
: MutVisitor
>(asyncness
: &mut Async
, vis
: &mut T
) {
830 Async
::Yes { span: _, closure_id, return_impl_trait_id }
=> {
831 vis
.visit_id(closure_id
);
832 vis
.visit_id(return_impl_trait_id
);
838 pub fn noop_visit_fn_decl
<T
: MutVisitor
>(decl
: &mut P
<FnDecl
>, vis
: &mut T
) {
839 let FnDecl { inputs, output }
= decl
.deref_mut();
840 inputs
.flat_map_in_place(|param
| vis
.flat_map_param(param
));
841 noop_visit_fn_ret_ty(output
, vis
);
844 pub fn noop_visit_fn_ret_ty
<T
: MutVisitor
>(fn_ret_ty
: &mut FnRetTy
, vis
: &mut T
) {
846 FnRetTy
::Default(span
) => vis
.visit_span(span
),
847 FnRetTy
::Ty(ty
) => vis
.visit_ty(ty
),
851 pub fn noop_visit_param_bound
<T
: MutVisitor
>(pb
: &mut GenericBound
, vis
: &mut T
) {
853 GenericBound
::Trait(ty
, _modifier
) => vis
.visit_poly_trait_ref(ty
),
854 GenericBound
::Outlives(lifetime
) => noop_visit_lifetime(lifetime
, vis
),
858 pub fn noop_flat_map_generic_param
<T
: MutVisitor
>(
859 mut param
: GenericParam
,
861 ) -> SmallVec
<[GenericParam
; 1]> {
862 let GenericParam { id, ident, attrs, bounds, kind, colon_span, is_placeholder: _ }
= &mut param
;
864 vis
.visit_ident(ident
);
865 if let Some(ref mut colon_span
) = colon_span
{
866 vis
.visit_span(colon_span
);
868 visit_thin_attrs(attrs
, vis
);
869 visit_vec(bounds
, |bound
| noop_visit_param_bound(bound
, vis
));
871 GenericParamKind
::Lifetime
=> {}
872 GenericParamKind
::Type { default }
=> {
873 visit_opt(default, |default| vis
.visit_ty(default));
875 GenericParamKind
::Const { ty, kw_span: _, default }
=> {
877 visit_opt(default, |default| vis
.visit_anon_const(default));
883 pub fn noop_visit_label
<T
: MutVisitor
>(Label { ident }
: &mut Label
, vis
: &mut T
) {
884 vis
.visit_ident(ident
);
887 fn noop_visit_lifetime
<T
: MutVisitor
>(Lifetime { id, ident }
: &mut Lifetime
, vis
: &mut T
) {
889 vis
.visit_ident(ident
);
892 pub fn noop_visit_generics
<T
: MutVisitor
>(generics
: &mut Generics
, vis
: &mut T
) {
893 let Generics { params, where_clause, span }
= generics
;
894 params
.flat_map_in_place(|param
| vis
.flat_map_generic_param(param
));
895 vis
.visit_where_clause(where_clause
);
896 vis
.visit_span(span
);
899 pub fn noop_visit_where_clause
<T
: MutVisitor
>(wc
: &mut WhereClause
, vis
: &mut T
) {
900 let WhereClause { has_where_token: _, predicates, span }
= wc
;
901 visit_vec(predicates
, |predicate
| vis
.visit_where_predicate(predicate
));
902 vis
.visit_span(span
);
905 pub fn noop_visit_where_predicate
<T
: MutVisitor
>(pred
: &mut WherePredicate
, vis
: &mut T
) {
907 WherePredicate
::BoundPredicate(bp
) => {
908 let WhereBoundPredicate { span, bound_generic_params, bounded_ty, bounds }
= bp
;
909 vis
.visit_span(span
);
910 bound_generic_params
.flat_map_in_place(|param
| vis
.flat_map_generic_param(param
));
911 vis
.visit_ty(bounded_ty
);
912 visit_vec(bounds
, |bound
| vis
.visit_param_bound(bound
));
914 WherePredicate
::RegionPredicate(rp
) => {
915 let WhereRegionPredicate { span, lifetime, bounds }
= rp
;
916 vis
.visit_span(span
);
917 noop_visit_lifetime(lifetime
, vis
);
918 visit_vec(bounds
, |bound
| noop_visit_param_bound(bound
, vis
));
920 WherePredicate
::EqPredicate(ep
) => {
921 let WhereEqPredicate { id, span, lhs_ty, rhs_ty }
= ep
;
923 vis
.visit_span(span
);
924 vis
.visit_ty(lhs_ty
);
925 vis
.visit_ty(rhs_ty
);
930 pub fn noop_visit_variant_data
<T
: MutVisitor
>(vdata
: &mut VariantData
, vis
: &mut T
) {
932 VariantData
::Struct(fields
, ..) => {
933 fields
.flat_map_in_place(|field
| vis
.flat_map_field_def(field
));
935 VariantData
::Tuple(fields
, id
) => {
936 fields
.flat_map_in_place(|field
| vis
.flat_map_field_def(field
));
939 VariantData
::Unit(id
) => vis
.visit_id(id
),
943 pub fn noop_visit_trait_ref
<T
: MutVisitor
>(TraitRef { path, ref_id }
: &mut TraitRef
, vis
: &mut T
) {
944 vis
.visit_path(path
);
945 vis
.visit_id(ref_id
);
948 pub fn noop_visit_poly_trait_ref
<T
: MutVisitor
>(p
: &mut PolyTraitRef
, vis
: &mut T
) {
949 let PolyTraitRef { bound_generic_params, trait_ref, span }
= p
;
950 bound_generic_params
.flat_map_in_place(|param
| vis
.flat_map_generic_param(param
));
951 vis
.visit_trait_ref(trait_ref
);
952 vis
.visit_span(span
);
955 pub fn noop_flat_map_field_def
<T
: MutVisitor
>(
958 ) -> SmallVec
<[FieldDef
; 1]> {
959 let FieldDef { span, ident, vis, id, ty, attrs, is_placeholder: _ }
= &mut fd
;
960 visitor
.visit_span(span
);
961 visit_opt(ident
, |ident
| visitor
.visit_ident(ident
));
962 visitor
.visit_vis(vis
);
963 visitor
.visit_id(id
);
964 visitor
.visit_ty(ty
);
965 visit_thin_attrs(attrs
, visitor
);
969 pub fn noop_flat_map_expr_field
<T
: MutVisitor
>(
972 ) -> SmallVec
<[ExprField
; 1]> {
973 let ExprField { ident, expr, span, is_shorthand: _, attrs, id, is_placeholder: _ }
= &mut f
;
974 vis
.visit_ident(ident
);
975 vis
.visit_expr(expr
);
977 vis
.visit_span(span
);
978 visit_thin_attrs(attrs
, vis
);
982 pub fn noop_visit_mt
<T
: MutVisitor
>(MutTy { ty, mutbl: _ }
: &mut MutTy
, vis
: &mut T
) {
986 pub fn noop_visit_block
<T
: MutVisitor
>(block
: &mut P
<Block
>, vis
: &mut T
) {
987 let Block { id, stmts, rules: _, span, tokens, could_be_bare_literal: _ }
= block
.deref_mut();
989 stmts
.flat_map_in_place(|stmt
| vis
.flat_map_stmt(stmt
));
990 vis
.visit_span(span
);
991 visit_lazy_tts(tokens
, vis
);
994 pub fn noop_visit_item_kind
<T
: MutVisitor
>(kind
: &mut ItemKind
, vis
: &mut T
) {
996 ItemKind
::ExternCrate(_orig_name
) => {}
997 ItemKind
::Use(use_tree
) => vis
.visit_use_tree(use_tree
),
998 ItemKind
::Static(ty
, _
, expr
) => {
1000 visit_opt(expr
, |expr
| vis
.visit_expr(expr
));
1002 ItemKind
::Const(defaultness
, ty
, expr
) => {
1003 visit_defaultness(defaultness
, vis
);
1005 visit_opt(expr
, |expr
| vis
.visit_expr(expr
));
1007 ItemKind
::Fn(box Fn { defaultness, generics, sig, body }
) => {
1008 visit_defaultness(defaultness
, vis
);
1009 visit_fn_sig(sig
, vis
);
1010 vis
.visit_generics(generics
);
1011 visit_opt(body
, |body
| vis
.visit_block(body
));
1013 ItemKind
::Mod(unsafety
, mod_kind
) => {
1014 visit_unsafety(unsafety
, vis
);
1016 ModKind
::Loaded(items
, _inline
, ModSpans { inner_span, inject_use_span }
) => {
1017 vis
.visit_span(inner_span
);
1018 vis
.visit_span(inject_use_span
);
1019 items
.flat_map_in_place(|item
| vis
.flat_map_item(item
));
1021 ModKind
::Unloaded
=> {}
1024 ItemKind
::ForeignMod(nm
) => vis
.visit_foreign_mod(nm
),
1025 ItemKind
::GlobalAsm(asm
) => vis
.visit_inline_asm(asm
),
1026 ItemKind
::TyAlias(box TyAlias
{
1027 defaultness
, generics
, where_clauses
, bounds
, ty
, ..
1029 visit_defaultness(defaultness
, vis
);
1030 vis
.visit_generics(generics
);
1031 vis
.visit_span(&mut where_clauses
.0.1);
1032 vis
.visit_span(&mut where_clauses
.1.1);
1033 visit_bounds(bounds
, vis
);
1034 visit_opt(ty
, |ty
| vis
.visit_ty(ty
));
1036 ItemKind
::Enum(EnumDef { variants }
, generics
) => {
1037 variants
.flat_map_in_place(|variant
| vis
.flat_map_variant(variant
));
1038 vis
.visit_generics(generics
);
1040 ItemKind
::Struct(variant_data
, generics
) | ItemKind
::Union(variant_data
, generics
) => {
1041 vis
.visit_variant_data(variant_data
);
1042 vis
.visit_generics(generics
);
1044 ItemKind
::Impl(box Impl
{
1054 visit_defaultness(defaultness
, vis
);
1055 visit_unsafety(unsafety
, vis
);
1056 vis
.visit_generics(generics
);
1057 visit_constness(constness
, vis
);
1058 visit_polarity(polarity
, vis
);
1059 visit_opt(of_trait
, |trait_ref
| vis
.visit_trait_ref(trait_ref
));
1060 vis
.visit_ty(self_ty
);
1061 items
.flat_map_in_place(|item
| vis
.flat_map_impl_item(item
));
1063 ItemKind
::Trait(box Trait { unsafety, is_auto: _, generics, bounds, items }
) => {
1064 visit_unsafety(unsafety
, vis
);
1065 vis
.visit_generics(generics
);
1066 visit_bounds(bounds
, vis
);
1067 items
.flat_map_in_place(|item
| vis
.flat_map_trait_item(item
));
1069 ItemKind
::TraitAlias(generics
, bounds
) => {
1070 vis
.visit_generics(generics
);
1071 visit_bounds(bounds
, vis
);
1073 ItemKind
::MacCall(m
) => vis
.visit_mac_call(m
),
1074 ItemKind
::MacroDef(def
) => vis
.visit_macro_def(def
),
1078 pub fn noop_flat_map_assoc_item
<T
: MutVisitor
>(
1079 mut item
: P
<AssocItem
>,
1081 ) -> SmallVec
<[P
<AssocItem
>; 1]> {
1082 let Item { id, ident, vis, attrs, kind, span, tokens }
= item
.deref_mut();
1083 visitor
.visit_id(id
);
1084 visitor
.visit_ident(ident
);
1085 visitor
.visit_vis(vis
);
1086 visit_attrs(attrs
, visitor
);
1088 AssocItemKind
::Const(defaultness
, ty
, expr
) => {
1089 visit_defaultness(defaultness
, visitor
);
1090 visitor
.visit_ty(ty
);
1091 visit_opt(expr
, |expr
| visitor
.visit_expr(expr
));
1093 AssocItemKind
::Fn(box Fn { defaultness, generics, sig, body }
) => {
1094 visit_defaultness(defaultness
, visitor
);
1095 visitor
.visit_generics(generics
);
1096 visit_fn_sig(sig
, visitor
);
1097 visit_opt(body
, |body
| visitor
.visit_block(body
));
1099 AssocItemKind
::TyAlias(box TyAlias
{
1107 visit_defaultness(defaultness
, visitor
);
1108 visitor
.visit_generics(generics
);
1109 visitor
.visit_span(&mut where_clauses
.0.1);
1110 visitor
.visit_span(&mut where_clauses
.1.1);
1111 visit_bounds(bounds
, visitor
);
1112 visit_opt(ty
, |ty
| visitor
.visit_ty(ty
));
1114 AssocItemKind
::MacCall(mac
) => visitor
.visit_mac_call(mac
),
1116 visitor
.visit_span(span
);
1117 visit_lazy_tts(tokens
, visitor
);
1121 pub fn noop_visit_fn_header
<T
: MutVisitor
>(header
: &mut FnHeader
, vis
: &mut T
) {
1122 let FnHeader { unsafety, asyncness, constness, ext: _ }
= header
;
1123 visit_constness(constness
, vis
);
1124 vis
.visit_asyncness(asyncness
);
1125 visit_unsafety(unsafety
, vis
);
1128 pub fn noop_visit_crate
<T
: MutVisitor
>(krate
: &mut Crate
, vis
: &mut T
) {
1129 let Crate { attrs, items, spans, id, is_placeholder: _ }
= krate
;
1131 visit_attrs(attrs
, vis
);
1132 items
.flat_map_in_place(|item
| vis
.flat_map_item(item
));
1133 let ModSpans { inner_span, inject_use_span }
= spans
;
1134 vis
.visit_span(inner_span
);
1135 vis
.visit_span(inject_use_span
);
1138 // Mutates one item into possibly many items.
1139 pub fn noop_flat_map_item
<T
: MutVisitor
>(
1142 ) -> SmallVec
<[P
<Item
>; 1]> {
1143 let Item { ident, attrs, id, kind, vis, span, tokens }
= item
.deref_mut();
1144 visitor
.visit_ident(ident
);
1145 visit_attrs(attrs
, visitor
);
1146 visitor
.visit_id(id
);
1147 visitor
.visit_item_kind(kind
);
1148 visitor
.visit_vis(vis
);
1149 visitor
.visit_span(span
);
1150 visit_lazy_tts(tokens
, visitor
);
1155 pub fn noop_flat_map_foreign_item
<T
: MutVisitor
>(
1156 mut item
: P
<ForeignItem
>,
1158 ) -> SmallVec
<[P
<ForeignItem
>; 1]> {
1159 let Item { ident, attrs, id, kind, vis, span, tokens }
= item
.deref_mut();
1160 visitor
.visit_id(id
);
1161 visitor
.visit_ident(ident
);
1162 visitor
.visit_vis(vis
);
1163 visit_attrs(attrs
, visitor
);
1165 ForeignItemKind
::Static(ty
, _
, expr
) => {
1166 visitor
.visit_ty(ty
);
1167 visit_opt(expr
, |expr
| visitor
.visit_expr(expr
));
1169 ForeignItemKind
::Fn(box Fn { defaultness, generics, sig, body }
) => {
1170 visit_defaultness(defaultness
, visitor
);
1171 visitor
.visit_generics(generics
);
1172 visit_fn_sig(sig
, visitor
);
1173 visit_opt(body
, |body
| visitor
.visit_block(body
));
1175 ForeignItemKind
::TyAlias(box TyAlias
{
1183 visit_defaultness(defaultness
, visitor
);
1184 visitor
.visit_generics(generics
);
1185 visitor
.visit_span(&mut where_clauses
.0.1);
1186 visitor
.visit_span(&mut where_clauses
.1.1);
1187 visit_bounds(bounds
, visitor
);
1188 visit_opt(ty
, |ty
| visitor
.visit_ty(ty
));
1190 ForeignItemKind
::MacCall(mac
) => visitor
.visit_mac_call(mac
),
1192 visitor
.visit_span(span
);
1193 visit_lazy_tts(tokens
, visitor
);
1197 pub fn noop_visit_pat
<T
: MutVisitor
>(pat
: &mut P
<Pat
>, vis
: &mut T
) {
1198 let Pat { id, kind, span, tokens }
= pat
.deref_mut();
1201 PatKind
::Wild
| PatKind
::Rest
=> {}
1202 PatKind
::Ident(_binding_mode
, ident
, sub
) => {
1203 vis
.visit_ident(ident
);
1204 visit_opt(sub
, |sub
| vis
.visit_pat(sub
));
1206 PatKind
::Lit(e
) => vis
.visit_expr(e
),
1207 PatKind
::TupleStruct(qself
, path
, elems
) => {
1208 vis
.visit_qself(qself
);
1209 vis
.visit_path(path
);
1210 visit_vec(elems
, |elem
| vis
.visit_pat(elem
));
1212 PatKind
::Path(qself
, path
) => {
1213 vis
.visit_qself(qself
);
1214 vis
.visit_path(path
);
1216 PatKind
::Struct(qself
, path
, fields
, _etc
) => {
1217 vis
.visit_qself(qself
);
1218 vis
.visit_path(path
);
1219 fields
.flat_map_in_place(|field
| vis
.flat_map_pat_field(field
));
1221 PatKind
::Box(inner
) => vis
.visit_pat(inner
),
1222 PatKind
::Ref(inner
, _mutbl
) => vis
.visit_pat(inner
),
1223 PatKind
::Range(e1
, e2
, Spanned { span: _, node: _ }
) => {
1224 visit_opt(e1
, |e
| vis
.visit_expr(e
));
1225 visit_opt(e2
, |e
| vis
.visit_expr(e
));
1226 vis
.visit_span(span
);
1228 PatKind
::Tuple(elems
) | PatKind
::Slice(elems
) | PatKind
::Or(elems
) => {
1229 visit_vec(elems
, |elem
| vis
.visit_pat(elem
))
1231 PatKind
::Paren(inner
) => vis
.visit_pat(inner
),
1232 PatKind
::MacCall(mac
) => vis
.visit_mac_call(mac
),
1234 vis
.visit_span(span
);
1235 visit_lazy_tts(tokens
, vis
);
1238 pub fn noop_visit_anon_const
<T
: MutVisitor
>(AnonConst { id, value }
: &mut AnonConst
, vis
: &mut T
) {
1240 vis
.visit_expr(value
);
1243 pub fn noop_visit_inline_asm
<T
: MutVisitor
>(asm
: &mut InlineAsm
, vis
: &mut T
) {
1244 for (op
, _
) in &mut asm
.operands
{
1246 InlineAsmOperand
::In { expr, .. }
1247 | InlineAsmOperand
::Out { expr: Some(expr), .. }
1248 | InlineAsmOperand
::InOut { expr, .. }
=> vis
.visit_expr(expr
),
1249 InlineAsmOperand
::Out { expr: None, .. }
=> {}
1250 InlineAsmOperand
::SplitInOut { in_expr, out_expr, .. }
=> {
1251 vis
.visit_expr(in_expr
);
1252 if let Some(out_expr
) = out_expr
{
1253 vis
.visit_expr(out_expr
);
1256 InlineAsmOperand
::Const { anon_const }
=> vis
.visit_anon_const(anon_const
),
1257 InlineAsmOperand
::Sym { sym }
=> vis
.visit_inline_asm_sym(sym
),
1262 pub fn noop_visit_inline_asm_sym
<T
: MutVisitor
>(
1263 InlineAsmSym { id, qself, path }
: &mut InlineAsmSym
,
1267 vis
.visit_qself(qself
);
1268 vis
.visit_path(path
);
1271 pub fn noop_visit_expr
<T
: MutVisitor
>(
1272 Expr { kind, id, span, attrs, tokens }
: &mut Expr
,
1276 ExprKind
::Box(expr
) => vis
.visit_expr(expr
),
1277 ExprKind
::Array(exprs
) => visit_exprs(exprs
, vis
),
1278 ExprKind
::ConstBlock(anon_const
) => {
1279 vis
.visit_anon_const(anon_const
);
1281 ExprKind
::Repeat(expr
, count
) => {
1282 vis
.visit_expr(expr
);
1283 vis
.visit_anon_const(count
);
1285 ExprKind
::Tup(exprs
) => visit_exprs(exprs
, vis
),
1286 ExprKind
::Call(f
, args
) => {
1288 visit_exprs(args
, vis
);
1290 ExprKind
::MethodCall(PathSegment { ident, id, args }
, exprs
, span
) => {
1291 vis
.visit_ident(ident
);
1293 visit_opt(args
, |args
| vis
.visit_generic_args(args
));
1294 visit_exprs(exprs
, vis
);
1295 vis
.visit_span(span
);
1297 ExprKind
::Binary(_binop
, lhs
, rhs
) => {
1298 vis
.visit_expr(lhs
);
1299 vis
.visit_expr(rhs
);
1301 ExprKind
::Unary(_unop
, ohs
) => vis
.visit_expr(ohs
),
1302 ExprKind
::Cast(expr
, ty
) => {
1303 vis
.visit_expr(expr
);
1306 ExprKind
::Type(expr
, ty
) => {
1307 vis
.visit_expr(expr
);
1310 ExprKind
::AddrOf(_
, _
, ohs
) => vis
.visit_expr(ohs
),
1311 ExprKind
::Let(pat
, scrutinee
, _
) => {
1313 vis
.visit_expr(scrutinee
);
1315 ExprKind
::If(cond
, tr
, fl
) => {
1316 vis
.visit_expr(cond
);
1317 vis
.visit_block(tr
);
1318 visit_opt(fl
, |fl
| vis
.visit_expr(fl
));
1320 ExprKind
::While(cond
, body
, label
) => {
1321 vis
.visit_expr(cond
);
1322 vis
.visit_block(body
);
1323 visit_opt(label
, |label
| vis
.visit_label(label
));
1325 ExprKind
::ForLoop(pat
, iter
, body
, label
) => {
1327 vis
.visit_expr(iter
);
1328 vis
.visit_block(body
);
1329 visit_opt(label
, |label
| vis
.visit_label(label
));
1331 ExprKind
::Loop(body
, label
) => {
1332 vis
.visit_block(body
);
1333 visit_opt(label
, |label
| vis
.visit_label(label
));
1335 ExprKind
::Match(expr
, arms
) => {
1336 vis
.visit_expr(expr
);
1337 arms
.flat_map_in_place(|arm
| vis
.flat_map_arm(arm
));
1339 ExprKind
::Closure(_capture_by
, asyncness
, _movability
, decl
, body
, span
) => {
1340 vis
.visit_asyncness(asyncness
);
1341 vis
.visit_fn_decl(decl
);
1342 vis
.visit_expr(body
);
1343 vis
.visit_span(span
);
1345 ExprKind
::Block(blk
, label
) => {
1346 vis
.visit_block(blk
);
1347 visit_opt(label
, |label
| vis
.visit_label(label
));
1349 ExprKind
::Async(_capture_by
, node_id
, body
) => {
1350 vis
.visit_id(node_id
);
1351 vis
.visit_block(body
);
1353 ExprKind
::Await(expr
) => vis
.visit_expr(expr
),
1354 ExprKind
::Assign(el
, er
, _
) => {
1358 ExprKind
::AssignOp(_op
, el
, er
) => {
1362 ExprKind
::Field(el
, ident
) => {
1364 vis
.visit_ident(ident
);
1366 ExprKind
::Index(el
, er
) => {
1370 ExprKind
::Range(e1
, e2
, _lim
) => {
1371 visit_opt(e1
, |e1
| vis
.visit_expr(e1
));
1372 visit_opt(e2
, |e2
| vis
.visit_expr(e2
));
1374 ExprKind
::Underscore
=> {}
1375 ExprKind
::Path(qself
, path
) => {
1376 vis
.visit_qself(qself
);
1377 vis
.visit_path(path
);
1379 ExprKind
::Break(label
, expr
) => {
1380 visit_opt(label
, |label
| vis
.visit_label(label
));
1381 visit_opt(expr
, |expr
| vis
.visit_expr(expr
));
1383 ExprKind
::Continue(label
) => {
1384 visit_opt(label
, |label
| vis
.visit_label(label
));
1386 ExprKind
::Ret(expr
) => {
1387 visit_opt(expr
, |expr
| vis
.visit_expr(expr
));
1389 ExprKind
::Yeet(expr
) => {
1390 visit_opt(expr
, |expr
| vis
.visit_expr(expr
));
1392 ExprKind
::InlineAsm(asm
) => vis
.visit_inline_asm(asm
),
1393 ExprKind
::MacCall(mac
) => vis
.visit_mac_call(mac
),
1394 ExprKind
::Struct(se
) => {
1395 let StructExpr { qself, path, fields, rest }
= se
.deref_mut();
1396 vis
.visit_qself(qself
);
1397 vis
.visit_path(path
);
1398 fields
.flat_map_in_place(|field
| vis
.flat_map_expr_field(field
));
1400 StructRest
::Base(expr
) => vis
.visit_expr(expr
),
1401 StructRest
::Rest(_span
) => {}
1402 StructRest
::None
=> {}
1405 ExprKind
::Paren(expr
) => {
1406 vis
.visit_expr(expr
);
1408 ExprKind
::Yield(expr
) => {
1409 visit_opt(expr
, |expr
| vis
.visit_expr(expr
));
1411 ExprKind
::Try(expr
) => vis
.visit_expr(expr
),
1412 ExprKind
::TryBlock(body
) => vis
.visit_block(body
),
1413 ExprKind
::Lit(_
) | ExprKind
::Err
=> {}
1416 vis
.visit_span(span
);
1417 visit_thin_attrs(attrs
, vis
);
1418 visit_lazy_tts(tokens
, vis
);
1421 pub fn noop_filter_map_expr
<T
: MutVisitor
>(mut e
: P
<Expr
>, vis
: &mut T
) -> Option
<P
<Expr
>> {
1423 vis
.visit_expr(&mut e
);
1428 pub fn noop_flat_map_stmt
<T
: MutVisitor
>(
1429 Stmt { kind, mut span, mut id }
: Stmt
,
1431 ) -> SmallVec
<[Stmt
; 1]> {
1432 vis
.visit_id(&mut id
);
1433 vis
.visit_span(&mut span
);
1434 let stmts
: SmallVec
<_
> = noop_flat_map_stmt_kind(kind
, vis
)
1436 .map(|kind
| Stmt { id, kind, span }
)
1438 if stmts
.len() > 1 {
1440 "cloning statement `NodeId`s is prohibited by default, \
1441 the visitor should implement custom statement visiting"
1447 pub fn noop_flat_map_stmt_kind
<T
: MutVisitor
>(
1450 ) -> SmallVec
<[StmtKind
; 1]> {
1452 StmtKind
::Local(mut local
) => smallvec
![StmtKind
::Local({
1453 vis
.visit_local(&mut local
);
1456 StmtKind
::Item(item
) => vis
.flat_map_item(item
).into_iter().map(StmtKind
::Item
).collect(),
1457 StmtKind
::Expr(expr
) => vis
.filter_map_expr(expr
).into_iter().map(StmtKind
::Expr
).collect(),
1458 StmtKind
::Semi(expr
) => vis
.filter_map_expr(expr
).into_iter().map(StmtKind
::Semi
).collect(),
1459 StmtKind
::Empty
=> smallvec
![StmtKind
::Empty
],
1460 StmtKind
::MacCall(mut mac
) => {
1461 let MacCallStmt { mac: mac_, style: _, attrs, tokens }
= mac
.deref_mut();
1462 vis
.visit_mac_call(mac_
);
1463 visit_thin_attrs(attrs
, vis
);
1464 visit_lazy_tts(tokens
, vis
);
1465 smallvec
![StmtKind
::MacCall(mac
)]
1470 pub fn noop_visit_vis
<T
: MutVisitor
>(visibility
: &mut Visibility
, vis
: &mut T
) {
1471 match &mut visibility
.kind
{
1472 VisibilityKind
::Public
| VisibilityKind
::Inherited
=> {}
1473 VisibilityKind
::Restricted { path, id }
=> {
1474 vis
.visit_path(path
);
1478 vis
.visit_span(&mut visibility
.span
);
1481 /// Some value for the AST node that is valid but possibly meaningless.
1482 pub trait DummyAstNode
{
1486 impl<T
> DummyAstNode
for Option
<T
> {
1487 fn dummy() -> Self {
1492 impl<T
: DummyAstNode
+ '
static> DummyAstNode
for P
<T
> {
1493 fn dummy() -> Self {
1494 P(DummyAstNode
::dummy())
1498 impl<T
> DummyAstNode
for ThinVec
<T
> {
1499 fn dummy() -> Self {
1504 impl DummyAstNode
for Item
{
1505 fn dummy() -> Self {
1507 attrs
: Default
::default(),
1509 span
: Default
::default(),
1511 kind
: VisibilityKind
::Public
,
1512 span
: Default
::default(),
1513 tokens
: Default
::default(),
1515 ident
: Ident
::empty(),
1516 kind
: ItemKind
::ExternCrate(None
),
1517 tokens
: Default
::default(),
1522 impl DummyAstNode
for Expr
{
1523 fn dummy() -> Self {
1526 kind
: ExprKind
::Err
,
1527 span
: Default
::default(),
1528 attrs
: Default
::default(),
1529 tokens
: Default
::default(),
1534 impl DummyAstNode
for Ty
{
1535 fn dummy() -> Self {
1539 span
: Default
::default(),
1540 tokens
: Default
::default(),
1545 impl DummyAstNode
for Pat
{
1546 fn dummy() -> Self {
1549 kind
: PatKind
::Wild
,
1550 span
: Default
::default(),
1551 tokens
: Default
::default(),
1556 impl DummyAstNode
for Stmt
{
1557 fn dummy() -> Self {
1558 Stmt { id: DUMMY_NODE_ID, kind: StmtKind::Empty, span: Default::default() }
1562 impl DummyAstNode
for Block
{
1563 fn dummy() -> Self {
1565 stmts
: Default
::default(),
1567 rules
: BlockCheckMode
::Default
,
1568 span
: Default
::default(),
1569 tokens
: Default
::default(),
1570 could_be_bare_literal
: Default
::default(),
1575 impl DummyAstNode
for Crate
{
1576 fn dummy() -> Self {
1578 attrs
: Default
::default(),
1579 items
: Default
::default(),
1580 spans
: Default
::default(),
1582 is_placeholder
: Default
::default(),