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_span
::source_map
::Spanned
;
18 use rustc_span
::symbol
::Ident
;
21 use smallvec
::{smallvec, Array, SmallVec}
;
22 use std
::ops
::DerefMut
;
23 use std
::{panic, ptr}
;
25 pub trait ExpectOne
<A
: Array
> {
26 fn expect_one(self, err
: &'
static str) -> A
::Item
;
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()
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;
42 // Methods in this trait have one of three forms:
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
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
54 // When writing these methods, it is better to use destructuring like this:
56 // fn visit_abc(&mut self, ABC { a, b, c: _ }: &mut ABC) {
61 // than to use field access like this:
63 // fn visit_abc(&mut self, abc: &mut ABC) {
64 // visit_a(&mut abc.a);
65 // visit_b(&mut abc.b);
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.
75 fn visit_crate(&mut self, c
: &mut Crate
) {
76 noop_visit_crate(c
, self)
79 fn visit_meta_list_item(&mut self, list_item
: &mut NestedMetaItem
) {
80 noop_visit_meta_list_item(list_item
, self);
83 fn visit_meta_item(&mut self, meta_item
: &mut MetaItem
) {
84 noop_visit_meta_item(meta_item
, self);
87 fn visit_use_tree(&mut self, use_tree
: &mut UseTree
) {
88 noop_visit_use_tree(use_tree
, self);
91 fn flat_map_foreign_item(&mut self, ni
: P
<ForeignItem
>) -> SmallVec
<[P
<ForeignItem
>; 1]> {
92 noop_flat_map_foreign_item(ni
, self)
95 fn flat_map_item(&mut self, i
: P
<Item
>) -> SmallVec
<[P
<Item
>; 1]> {
96 noop_flat_map_item(i
, self)
99 fn visit_fn_header(&mut self, header
: &mut FnHeader
) {
100 noop_visit_fn_header(header
, self);
103 fn flat_map_field_def(&mut self, fd
: FieldDef
) -> SmallVec
<[FieldDef
; 1]> {
104 noop_flat_map_field_def(fd
, self)
107 fn visit_item_kind(&mut self, i
: &mut ItemKind
) {
108 noop_visit_item_kind(i
, self);
111 fn flat_map_trait_item(&mut self, i
: P
<AssocItem
>) -> SmallVec
<[P
<AssocItem
>; 1]> {
112 noop_flat_map_assoc_item(i
, self)
115 fn flat_map_impl_item(&mut self, i
: P
<AssocItem
>) -> SmallVec
<[P
<AssocItem
>; 1]> {
116 noop_flat_map_assoc_item(i
, self)
119 fn visit_fn_decl(&mut self, d
: &mut P
<FnDecl
>) {
120 noop_visit_fn_decl(d
, self);
123 fn visit_asyncness(&mut self, a
: &mut Async
) {
124 noop_visit_asyncness(a
, self);
127 fn visit_closure_binder(&mut self, b
: &mut ClosureBinder
) {
128 noop_visit_closure_binder(b
, self);
131 fn visit_block(&mut self, b
: &mut P
<Block
>) {
132 noop_visit_block(b
, self);
135 fn flat_map_stmt(&mut self, s
: Stmt
) -> SmallVec
<[Stmt
; 1]> {
136 noop_flat_map_stmt(s
, self)
139 fn flat_map_arm(&mut self, arm
: Arm
) -> SmallVec
<[Arm
; 1]> {
140 noop_flat_map_arm(arm
, self)
143 fn visit_pat(&mut self, p
: &mut P
<Pat
>) {
144 noop_visit_pat(p
, self);
147 fn visit_anon_const(&mut self, c
: &mut AnonConst
) {
148 noop_visit_anon_const(c
, self);
151 fn visit_expr(&mut self, e
: &mut P
<Expr
>) {
152 noop_visit_expr(e
, self);
155 /// This method is a hack to workaround unstable of `stmt_expr_attributes`.
156 /// It can be removed once that feature is stabilized.
157 fn visit_method_receiver_expr(&mut self, ex
: &mut P
<Expr
>) {
161 fn filter_map_expr(&mut self, e
: P
<Expr
>) -> Option
<P
<Expr
>> {
162 noop_filter_map_expr(e
, self)
165 fn visit_generic_arg(&mut self, arg
: &mut GenericArg
) {
166 noop_visit_generic_arg(arg
, self);
169 fn visit_ty(&mut self, t
: &mut P
<Ty
>) {
170 noop_visit_ty(t
, self);
173 fn visit_lifetime(&mut self, l
: &mut Lifetime
) {
174 noop_visit_lifetime(l
, self);
177 fn visit_constraint(&mut self, t
: &mut AssocConstraint
) {
178 noop_visit_constraint(t
, self);
181 fn visit_foreign_mod(&mut self, nm
: &mut ForeignMod
) {
182 noop_visit_foreign_mod(nm
, self);
185 fn flat_map_variant(&mut self, v
: Variant
) -> SmallVec
<[Variant
; 1]> {
186 noop_flat_map_variant(v
, self)
189 fn visit_ident(&mut self, i
: &mut Ident
) {
190 noop_visit_ident(i
, self);
193 fn visit_path(&mut self, p
: &mut Path
) {
194 noop_visit_path(p
, self);
197 fn visit_qself(&mut self, qs
: &mut Option
<P
<QSelf
>>) {
198 noop_visit_qself(qs
, self);
201 fn visit_generic_args(&mut self, p
: &mut GenericArgs
) {
202 noop_visit_generic_args(p
, self);
205 fn visit_angle_bracketed_parameter_data(&mut self, p
: &mut AngleBracketedArgs
) {
206 noop_visit_angle_bracketed_parameter_data(p
, self);
209 fn visit_parenthesized_parameter_data(&mut self, p
: &mut ParenthesizedArgs
) {
210 noop_visit_parenthesized_parameter_data(p
, self);
213 fn visit_local(&mut self, l
: &mut P
<Local
>) {
214 noop_visit_local(l
, self);
217 fn visit_mac_call(&mut self, mac
: &mut MacCall
) {
218 noop_visit_mac(mac
, self);
221 fn visit_macro_def(&mut self, def
: &mut MacroDef
) {
222 noop_visit_macro_def(def
, self);
225 fn visit_label(&mut self, label
: &mut Label
) {
226 noop_visit_label(label
, self);
229 fn visit_attribute(&mut self, at
: &mut Attribute
) {
230 noop_visit_attribute(at
, self);
233 fn flat_map_param(&mut self, param
: Param
) -> SmallVec
<[Param
; 1]> {
234 noop_flat_map_param(param
, self)
237 fn visit_generics(&mut self, generics
: &mut Generics
) {
238 noop_visit_generics(generics
, self);
241 fn visit_trait_ref(&mut self, tr
: &mut TraitRef
) {
242 noop_visit_trait_ref(tr
, self);
245 fn visit_poly_trait_ref(&mut self, p
: &mut PolyTraitRef
) {
246 noop_visit_poly_trait_ref(p
, self);
249 fn visit_variant_data(&mut self, vdata
: &mut VariantData
) {
250 noop_visit_variant_data(vdata
, self);
253 fn flat_map_generic_param(&mut self, param
: GenericParam
) -> SmallVec
<[GenericParam
; 1]> {
254 noop_flat_map_generic_param(param
, self)
257 fn visit_param_bound(&mut self, tpb
: &mut GenericBound
) {
258 noop_visit_param_bound(tpb
, self);
261 fn visit_mt(&mut self, mt
: &mut MutTy
) {
262 noop_visit_mt(mt
, self);
265 fn flat_map_expr_field(&mut self, f
: ExprField
) -> SmallVec
<[ExprField
; 1]> {
266 noop_flat_map_expr_field(f
, self)
269 fn visit_where_clause(&mut self, where_clause
: &mut WhereClause
) {
270 noop_visit_where_clause(where_clause
, self);
273 fn visit_where_predicate(&mut self, where_predicate
: &mut WherePredicate
) {
274 noop_visit_where_predicate(where_predicate
, self);
277 fn visit_vis(&mut self, vis
: &mut Visibility
) {
278 noop_visit_vis(vis
, self);
281 fn visit_id(&mut self, _id
: &mut NodeId
) {
285 fn visit_span(&mut self, _sp
: &mut Span
) {
289 fn flat_map_pat_field(&mut self, fp
: PatField
) -> SmallVec
<[PatField
; 1]> {
290 noop_flat_map_pat_field(fp
, self)
293 fn visit_inline_asm(&mut self, asm
: &mut InlineAsm
) {
294 noop_visit_inline_asm(asm
, self)
297 fn visit_inline_asm_sym(&mut self, sym
: &mut InlineAsmSym
) {
298 noop_visit_inline_asm_sym(sym
, self)
302 /// Use a map-style function (`FnOnce(T) -> T`) to overwrite a `&mut T`. Useful
303 /// when using a `flat_map_*` or `filter_map_*` method within a `visit_`
306 // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
307 pub fn visit_clobber
<T
: DummyAstNode
>(t
: &mut T
, f
: impl FnOnce(T
) -> T
) {
309 // Safe because `t` is used in a read-only fashion by `read()` before
310 // being overwritten by `write()`.
311 let old_t
= ptr
::read(t
);
313 panic
::catch_unwind(panic
::AssertUnwindSafe(|| f(old_t
))).unwrap_or_else(|err
| {
314 // Set `t` to some valid but possible meaningless value,
315 // and pass the fatal error further.
316 ptr
::write(t
, T
::dummy());
317 panic
::resume_unwind(err
);
319 ptr
::write(t
, new_t
);
323 // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
325 pub fn visit_vec
<T
, F
>(elems
: &mut Vec
<T
>, mut visit_elem
: F
)
334 // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
336 pub fn visit_opt
<T
, F
>(opt
: &mut Option
<T
>, mut visit_elem
: F
)
340 if let Some(elem
) = opt
{
345 // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
346 pub fn visit_attrs
<T
: MutVisitor
>(attrs
: &mut AttrVec
, vis
: &mut T
) {
347 for attr
in attrs
.iter_mut() {
348 vis
.visit_attribute(attr
);
352 // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
353 pub fn visit_exprs
<T
: MutVisitor
>(exprs
: &mut Vec
<P
<Expr
>>, vis
: &mut T
) {
354 exprs
.flat_map_in_place(|expr
| vis
.filter_map_expr(expr
))
357 // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
358 pub fn visit_bounds
<T
: MutVisitor
>(bounds
: &mut GenericBounds
, vis
: &mut T
) {
359 visit_vec(bounds
, |bound
| vis
.visit_param_bound(bound
));
362 // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
363 pub fn visit_fn_sig
<T
: MutVisitor
>(FnSig { header, decl, span }
: &mut FnSig
, vis
: &mut T
) {
364 vis
.visit_fn_header(header
);
365 vis
.visit_fn_decl(decl
);
366 vis
.visit_span(span
);
369 // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
370 pub fn visit_attr_args
<T
: MutVisitor
>(args
: &mut AttrArgs
, vis
: &mut T
) {
372 AttrArgs
::Empty
=> {}
373 AttrArgs
::Delimited(args
) => visit_delim_args(args
, vis
),
374 AttrArgs
::Eq(eq_span
, AttrArgsEq
::Ast(expr
)) => {
375 vis
.visit_span(eq_span
);
376 vis
.visit_expr(expr
);
378 AttrArgs
::Eq(_
, AttrArgsEq
::Hir(lit
)) => {
379 unreachable
!("in literal form when visiting mac args eq: {:?}", lit
)
384 // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
385 pub fn visit_delim_args
<T
: MutVisitor
>(args
: &mut DelimArgs
, vis
: &mut T
) {
386 let DelimArgs { dspan, delim: _, tokens }
= args
;
387 visit_delim_span(dspan
, vis
);
388 visit_tts(tokens
, vis
);
391 pub fn visit_delim_span
<T
: MutVisitor
>(dspan
: &mut DelimSpan
, vis
: &mut T
) {
392 vis
.visit_span(&mut dspan
.open
);
393 vis
.visit_span(&mut dspan
.close
);
396 pub fn noop_flat_map_pat_field
<T
: MutVisitor
>(
399 ) -> SmallVec
<[PatField
; 1]> {
400 let PatField { attrs, id, ident, is_placeholder: _, is_shorthand: _, pat, span }
= &mut fp
;
402 vis
.visit_ident(ident
);
404 vis
.visit_span(span
);
405 visit_attrs(attrs
, vis
);
409 pub fn noop_visit_use_tree
<T
: MutVisitor
>(use_tree
: &mut UseTree
, vis
: &mut T
) {
410 let UseTree { prefix, kind, span }
= use_tree
;
411 vis
.visit_path(prefix
);
413 UseTreeKind
::Simple(rename
) => visit_opt(rename
, |rename
| vis
.visit_ident(rename
)),
414 UseTreeKind
::Nested(items
) => {
415 for (tree
, id
) in items
{
416 vis
.visit_use_tree(tree
);
420 UseTreeKind
::Glob
=> {}
422 vis
.visit_span(span
);
425 pub fn noop_flat_map_arm
<T
: MutVisitor
>(mut arm
: Arm
, vis
: &mut T
) -> SmallVec
<[Arm
; 1]> {
426 let Arm { attrs, pat, guard, body, span, id, is_placeholder: _ }
= &mut arm
;
427 visit_attrs(attrs
, vis
);
430 visit_opt(guard
, |guard
| vis
.visit_expr(guard
));
431 vis
.visit_expr(body
);
432 vis
.visit_span(span
);
436 pub fn noop_visit_constraint
<T
: MutVisitor
>(
437 AssocConstraint { id, ident, gen_args, kind, span }
: &mut AssocConstraint
,
441 vis
.visit_ident(ident
);
442 if let Some(gen_args
) = gen_args
{
443 vis
.visit_generic_args(gen_args
);
446 AssocConstraintKind
::Equality { term }
=> match term
{
447 Term
::Ty(ty
) => vis
.visit_ty(ty
),
448 Term
::Const(c
) => vis
.visit_anon_const(c
),
450 AssocConstraintKind
::Bound { bounds }
=> visit_bounds(bounds
, vis
),
452 vis
.visit_span(span
);
455 pub fn noop_visit_ty
<T
: MutVisitor
>(ty
: &mut P
<Ty
>, vis
: &mut T
) {
456 let Ty { id, kind, span, tokens }
= ty
.deref_mut();
459 TyKind
::Infer
| TyKind
::ImplicitSelf
| TyKind
::Err
| TyKind
::Never
| TyKind
::CVarArgs
=> {}
460 TyKind
::Slice(ty
) => vis
.visit_ty(ty
),
461 TyKind
::Ptr(mt
) => vis
.visit_mt(mt
),
462 TyKind
::Rptr(lt
, mt
) => {
463 visit_opt(lt
, |lt
| noop_visit_lifetime(lt
, vis
));
466 TyKind
::BareFn(bft
) => {
467 let BareFnTy { unsafety, ext: _, generic_params, decl, decl_span }
= bft
.deref_mut();
468 visit_unsafety(unsafety
, vis
);
469 generic_params
.flat_map_in_place(|param
| vis
.flat_map_generic_param(param
));
470 vis
.visit_fn_decl(decl
);
471 vis
.visit_span(decl_span
);
473 TyKind
::Tup(tys
) => visit_vec(tys
, |ty
| vis
.visit_ty(ty
)),
474 TyKind
::Paren(ty
) => vis
.visit_ty(ty
),
475 TyKind
::Path(qself
, path
) => {
476 vis
.visit_qself(qself
);
477 vis
.visit_path(path
);
479 TyKind
::Array(ty
, length
) => {
481 vis
.visit_anon_const(length
);
483 TyKind
::Typeof(expr
) => vis
.visit_anon_const(expr
),
484 TyKind
::TraitObject(bounds
, _syntax
) => {
485 visit_vec(bounds
, |bound
| vis
.visit_param_bound(bound
))
487 TyKind
::ImplTrait(id
, bounds
) => {
489 visit_vec(bounds
, |bound
| vis
.visit_param_bound(bound
));
491 TyKind
::MacCall(mac
) => vis
.visit_mac_call(mac
),
493 vis
.visit_span(span
);
494 visit_lazy_tts(tokens
, vis
);
497 pub fn noop_visit_foreign_mod
<T
: MutVisitor
>(foreign_mod
: &mut ForeignMod
, vis
: &mut T
) {
498 let ForeignMod { unsafety, abi: _, items }
= foreign_mod
;
499 visit_unsafety(unsafety
, vis
);
500 items
.flat_map_in_place(|item
| vis
.flat_map_foreign_item(item
));
503 pub fn noop_flat_map_variant
<T
: MutVisitor
>(
504 mut variant
: Variant
,
506 ) -> SmallVec
<[Variant
; 1]> {
507 let Variant { ident, vis, attrs, id, data, disr_expr, span, is_placeholder: _ }
= &mut variant
;
508 visitor
.visit_ident(ident
);
509 visitor
.visit_vis(vis
);
510 visit_attrs(attrs
, visitor
);
511 visitor
.visit_id(id
);
512 visitor
.visit_variant_data(data
);
513 visit_opt(disr_expr
, |disr_expr
| visitor
.visit_anon_const(disr_expr
));
514 visitor
.visit_span(span
);
518 pub fn noop_visit_ident
<T
: MutVisitor
>(Ident { name: _, span }
: &mut Ident
, vis
: &mut T
) {
519 vis
.visit_span(span
);
522 pub fn noop_visit_path
<T
: MutVisitor
>(Path { segments, span, tokens }
: &mut Path
, vis
: &mut T
) {
523 vis
.visit_span(span
);
524 for PathSegment { ident, id, args }
in segments
{
525 vis
.visit_ident(ident
);
527 visit_opt(args
, |args
| vis
.visit_generic_args(args
));
529 visit_lazy_tts(tokens
, vis
);
532 pub fn noop_visit_qself
<T
: MutVisitor
>(qself
: &mut Option
<P
<QSelf
>>, vis
: &mut T
) {
533 visit_opt(qself
, |qself
| {
534 let QSelf { ty, path_span, position: _ }
= &mut **qself
;
536 vis
.visit_span(path_span
);
540 pub fn noop_visit_generic_args
<T
: MutVisitor
>(generic_args
: &mut GenericArgs
, vis
: &mut T
) {
542 GenericArgs
::AngleBracketed(data
) => vis
.visit_angle_bracketed_parameter_data(data
),
543 GenericArgs
::Parenthesized(data
) => vis
.visit_parenthesized_parameter_data(data
),
547 pub fn noop_visit_generic_arg
<T
: MutVisitor
>(arg
: &mut GenericArg
, vis
: &mut T
) {
549 GenericArg
::Lifetime(lt
) => vis
.visit_lifetime(lt
),
550 GenericArg
::Type(ty
) => vis
.visit_ty(ty
),
551 GenericArg
::Const(ct
) => vis
.visit_anon_const(ct
),
555 pub fn noop_visit_angle_bracketed_parameter_data
<T
: MutVisitor
>(
556 data
: &mut AngleBracketedArgs
,
559 let AngleBracketedArgs { args, span }
= data
;
560 visit_vec(args
, |arg
| match arg
{
561 AngleBracketedArg
::Arg(arg
) => vis
.visit_generic_arg(arg
),
562 AngleBracketedArg
::Constraint(constraint
) => vis
.visit_constraint(constraint
),
564 vis
.visit_span(span
);
567 pub fn noop_visit_parenthesized_parameter_data
<T
: MutVisitor
>(
568 args
: &mut ParenthesizedArgs
,
571 let ParenthesizedArgs { inputs, output, span, .. }
= args
;
572 visit_vec(inputs
, |input
| vis
.visit_ty(input
));
573 noop_visit_fn_ret_ty(output
, vis
);
574 vis
.visit_span(span
);
577 pub fn noop_visit_local
<T
: MutVisitor
>(local
: &mut P
<Local
>, vis
: &mut T
) {
578 let Local { id, pat, ty, kind, span, attrs, tokens }
= local
.deref_mut();
581 visit_opt(ty
, |ty
| vis
.visit_ty(ty
));
583 LocalKind
::Decl
=> {}
584 LocalKind
::Init(init
) => {
585 vis
.visit_expr(init
);
587 LocalKind
::InitElse(init
, els
) => {
588 vis
.visit_expr(init
);
589 vis
.visit_block(els
);
592 vis
.visit_span(span
);
593 visit_attrs(attrs
, vis
);
594 visit_lazy_tts(tokens
, vis
);
597 pub fn noop_visit_attribute
<T
: MutVisitor
>(attr
: &mut Attribute
, vis
: &mut T
) {
598 let Attribute { kind, id: _, style: _, span }
= attr
;
600 AttrKind
::Normal(normal
) => {
601 let NormalAttr { item: AttrItem { path, args, tokens }
, tokens
: attr_tokens
} =
603 vis
.visit_path(path
);
604 visit_attr_args(args
, vis
);
605 visit_lazy_tts(tokens
, vis
);
606 visit_lazy_tts(attr_tokens
, vis
);
608 AttrKind
::DocComment(..) => {}
610 vis
.visit_span(span
);
613 pub fn noop_visit_mac
<T
: MutVisitor
>(mac
: &mut MacCall
, vis
: &mut T
) {
614 let MacCall { path, args, prior_type_ascription: _ }
= mac
;
615 vis
.visit_path(path
);
616 visit_delim_args(args
, vis
);
619 pub fn noop_visit_macro_def
<T
: MutVisitor
>(macro_def
: &mut MacroDef
, vis
: &mut T
) {
620 let MacroDef { body, macro_rules: _ }
= macro_def
;
621 visit_delim_args(body
, vis
);
624 pub fn noop_visit_meta_list_item
<T
: MutVisitor
>(li
: &mut NestedMetaItem
, vis
: &mut T
) {
626 NestedMetaItem
::MetaItem(mi
) => vis
.visit_meta_item(mi
),
627 NestedMetaItem
::Lit(_lit
) => {}
631 pub fn noop_visit_meta_item
<T
: MutVisitor
>(mi
: &mut MetaItem
, vis
: &mut T
) {
632 let MetaItem { path: _, kind, span }
= mi
;
634 MetaItemKind
::Word
=> {}
635 MetaItemKind
::List(mis
) => visit_vec(mis
, |mi
| vis
.visit_meta_list_item(mi
)),
636 MetaItemKind
::NameValue(_s
) => {}
638 vis
.visit_span(span
);
641 pub fn noop_flat_map_param
<T
: MutVisitor
>(mut param
: Param
, vis
: &mut T
) -> SmallVec
<[Param
; 1]> {
642 let Param { attrs, id, pat, span, ty, is_placeholder: _ }
= &mut param
;
644 visit_attrs(attrs
, vis
);
646 vis
.visit_span(span
);
651 // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
652 pub fn visit_attr_tt
<T
: MutVisitor
>(tt
: &mut AttrTokenTree
, vis
: &mut T
) {
654 AttrTokenTree
::Token(token
, _
) => {
655 visit_token(token
, vis
);
657 AttrTokenTree
::Delimited(DelimSpan { open, close }
, _delim
, tts
) => {
658 vis
.visit_span(open
);
659 vis
.visit_span(close
);
660 visit_attr_tts(tts
, vis
);
662 AttrTokenTree
::Attributes(data
) => {
663 for attr
in &mut *data
.attrs
{
664 match &mut attr
.kind
{
665 AttrKind
::Normal(normal
) => {
666 visit_lazy_tts(&mut normal
.tokens
, vis
);
668 AttrKind
::DocComment(..) => {
669 vis
.visit_span(&mut attr
.span
);
673 visit_lazy_tts_opt_mut(Some(&mut data
.tokens
), vis
);
678 // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
679 pub fn visit_tt
<T
: MutVisitor
>(tt
: &mut TokenTree
, vis
: &mut T
) {
681 TokenTree
::Token(token
, _
) => {
682 visit_token(token
, vis
);
684 TokenTree
::Delimited(DelimSpan { open, close }
, _delim
, tts
) => {
685 vis
.visit_span(open
);
686 vis
.visit_span(close
);
692 // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
693 pub fn visit_tts
<T
: MutVisitor
>(TokenStream(tts
): &mut TokenStream
, vis
: &mut T
) {
694 if T
::VISIT_TOKENS
&& !tts
.is_empty() {
695 let tts
= Lrc
::make_mut(tts
);
696 visit_vec(tts
, |tree
| visit_tt(tree
, vis
));
700 pub fn visit_attr_tts
<T
: MutVisitor
>(AttrTokenStream(tts
): &mut AttrTokenStream
, vis
: &mut T
) {
701 if T
::VISIT_TOKENS
&& !tts
.is_empty() {
702 let tts
= Lrc
::make_mut(tts
);
703 visit_vec(tts
, |tree
| visit_attr_tt(tree
, vis
));
707 pub fn visit_lazy_tts_opt_mut
<T
: MutVisitor
>(
708 lazy_tts
: Option
<&mut LazyAttrTokenStream
>,
712 if let Some(lazy_tts
) = lazy_tts
{
713 let mut tts
= lazy_tts
.to_attr_token_stream();
714 visit_attr_tts(&mut tts
, vis
);
715 *lazy_tts
= LazyAttrTokenStream
::new(tts
);
720 pub fn visit_lazy_tts
<T
: MutVisitor
>(lazy_tts
: &mut Option
<LazyAttrTokenStream
>, vis
: &mut T
) {
721 visit_lazy_tts_opt_mut(lazy_tts
.as_mut(), vis
);
724 /// Applies ident visitor if it's an ident; applies other visits to interpolated nodes.
725 /// In practice the ident part is not actually used by specific visitors right now,
726 /// but there's a test below checking that it works.
727 // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
728 pub fn visit_token
<T
: MutVisitor
>(t
: &mut Token
, vis
: &mut T
) {
729 let Token { kind, span }
= t
;
731 token
::Ident(name
, _
) | token
::Lifetime(name
) => {
732 let mut ident
= Ident
::new(*name
, *span
);
733 vis
.visit_ident(&mut ident
);
736 return; // Avoid visiting the span for the second time.
738 token
::Interpolated(nt
) => {
739 visit_nonterminal(Lrc
::make_mut(nt
), vis
);
743 vis
.visit_span(span
);
746 // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
747 /// Applies the visitor to elements of interpolated nodes.
749 // N.B., this can occur only when applying a visitor to partially expanded
750 // code, where parsed pieces have gotten implanted ito *other* macro
751 // invocations. This is relevant for macro hygiene, but possibly not elsewhere.
753 // One problem here occurs because the types for flat_map_item, flat_map_stmt,
754 // etc., allow the visitor to return *multiple* items; this is a problem for the
755 // nodes here, because they insist on having exactly one piece. One solution
756 // would be to mangle the MutVisitor trait to include one-to-many and
757 // one-to-one versions of these entry points, but that would probably confuse a
758 // lot of people and help very few. Instead, I'm just going to put in dynamic
759 // checks. I think the performance impact of this will be pretty much
760 // nonexistent. The danger is that someone will apply a `MutVisitor` to a
761 // partially expanded node, and will be confused by the fact that their
762 // `flat_map_item` or `flat_map_stmt` isn't getting called on `NtItem` or `NtStmt`
763 // nodes. Hopefully they'll wind up reading this comment, and doing something
766 // BTW, design choice: I considered just changing the type of, e.g., `NtItem` to
767 // contain multiple items, but decided against it when I looked at
768 // `parse_item_or_view_item` and tried to figure out what I would do with
769 // multiple items there....
770 pub fn visit_nonterminal
<T
: MutVisitor
>(nt
: &mut token
::Nonterminal
, vis
: &mut T
) {
772 token
::NtItem(item
) => visit_clobber(item
, |item
| {
773 // This is probably okay, because the only visitors likely to
774 // peek inside interpolated nodes will be renamings/markings,
775 // which map single items to single items.
776 vis
.flat_map_item(item
).expect_one("expected visitor to produce exactly one item")
778 token
::NtBlock(block
) => vis
.visit_block(block
),
779 token
::NtStmt(stmt
) => visit_clobber(stmt
, |stmt
| {
780 // See reasoning above.
782 vis
.flat_map_stmt(stmt
).expect_one("expected visitor to produce exactly one item")
785 token
::NtPat(pat
) => vis
.visit_pat(pat
),
786 token
::NtExpr(expr
) => vis
.visit_expr(expr
),
787 token
::NtTy(ty
) => vis
.visit_ty(ty
),
788 token
::NtIdent(ident
, _is_raw
) => vis
.visit_ident(ident
),
789 token
::NtLifetime(ident
) => vis
.visit_ident(ident
),
790 token
::NtLiteral(expr
) => vis
.visit_expr(expr
),
791 token
::NtMeta(item
) => {
792 let AttrItem { path, args, tokens }
= item
.deref_mut();
793 vis
.visit_path(path
);
794 visit_attr_args(args
, vis
);
795 visit_lazy_tts(tokens
, vis
);
797 token
::NtPath(path
) => vis
.visit_path(path
),
798 token
::NtVis(visib
) => vis
.visit_vis(visib
),
802 // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
803 pub fn visit_defaultness
<T
: MutVisitor
>(defaultness
: &mut Defaultness
, vis
: &mut T
) {
805 Defaultness
::Default(span
) => vis
.visit_span(span
),
806 Defaultness
::Final
=> {}
810 // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
811 pub fn visit_unsafety
<T
: MutVisitor
>(unsafety
: &mut Unsafe
, vis
: &mut T
) {
813 Unsafe
::Yes(span
) => vis
.visit_span(span
),
818 // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
819 pub fn visit_polarity
<T
: MutVisitor
>(polarity
: &mut ImplPolarity
, vis
: &mut T
) {
821 ImplPolarity
::Positive
=> {}
822 ImplPolarity
::Negative(span
) => vis
.visit_span(span
),
826 // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
827 pub fn visit_constness
<T
: MutVisitor
>(constness
: &mut Const
, vis
: &mut T
) {
829 Const
::Yes(span
) => vis
.visit_span(span
),
834 pub fn noop_visit_closure_binder
<T
: MutVisitor
>(binder
: &mut ClosureBinder
, vis
: &mut T
) {
836 ClosureBinder
::NotPresent
=> {}
837 ClosureBinder
::For { span: _, generic_params }
=> {
838 let mut vec
= std
::mem
::take(generic_params
).into_vec();
839 vec
.flat_map_in_place(|param
| vis
.flat_map_generic_param(param
));
840 *generic_params
= P
::from_vec(vec
);
845 pub fn noop_visit_asyncness
<T
: MutVisitor
>(asyncness
: &mut Async
, vis
: &mut T
) {
847 Async
::Yes { span: _, closure_id, return_impl_trait_id }
=> {
848 vis
.visit_id(closure_id
);
849 vis
.visit_id(return_impl_trait_id
);
855 pub fn noop_visit_fn_decl
<T
: MutVisitor
>(decl
: &mut P
<FnDecl
>, vis
: &mut T
) {
856 let FnDecl { inputs, output }
= decl
.deref_mut();
857 inputs
.flat_map_in_place(|param
| vis
.flat_map_param(param
));
858 noop_visit_fn_ret_ty(output
, vis
);
861 pub fn noop_visit_fn_ret_ty
<T
: MutVisitor
>(fn_ret_ty
: &mut FnRetTy
, vis
: &mut T
) {
863 FnRetTy
::Default(span
) => vis
.visit_span(span
),
864 FnRetTy
::Ty(ty
) => vis
.visit_ty(ty
),
868 pub fn noop_visit_param_bound
<T
: MutVisitor
>(pb
: &mut GenericBound
, vis
: &mut T
) {
870 GenericBound
::Trait(ty
, _modifier
) => vis
.visit_poly_trait_ref(ty
),
871 GenericBound
::Outlives(lifetime
) => noop_visit_lifetime(lifetime
, vis
),
875 pub fn noop_flat_map_generic_param
<T
: MutVisitor
>(
876 mut param
: GenericParam
,
878 ) -> SmallVec
<[GenericParam
; 1]> {
879 let GenericParam { id, ident, attrs, bounds, kind, colon_span, is_placeholder: _ }
= &mut param
;
881 vis
.visit_ident(ident
);
882 if let Some(colon_span
) = colon_span
{
883 vis
.visit_span(colon_span
);
885 visit_attrs(attrs
, vis
);
886 visit_vec(bounds
, |bound
| noop_visit_param_bound(bound
, vis
));
888 GenericParamKind
::Lifetime
=> {}
889 GenericParamKind
::Type { default }
=> {
890 visit_opt(default, |default| vis
.visit_ty(default));
892 GenericParamKind
::Const { ty, kw_span: _, default }
=> {
894 visit_opt(default, |default| vis
.visit_anon_const(default));
900 pub fn noop_visit_label
<T
: MutVisitor
>(Label { ident }
: &mut Label
, vis
: &mut T
) {
901 vis
.visit_ident(ident
);
904 fn noop_visit_lifetime
<T
: MutVisitor
>(Lifetime { id, ident }
: &mut Lifetime
, vis
: &mut T
) {
906 vis
.visit_ident(ident
);
909 pub fn noop_visit_generics
<T
: MutVisitor
>(generics
: &mut Generics
, vis
: &mut T
) {
910 let Generics { params, where_clause, span }
= generics
;
911 params
.flat_map_in_place(|param
| vis
.flat_map_generic_param(param
));
912 vis
.visit_where_clause(where_clause
);
913 vis
.visit_span(span
);
916 pub fn noop_visit_where_clause
<T
: MutVisitor
>(wc
: &mut WhereClause
, vis
: &mut T
) {
917 let WhereClause { has_where_token: _, predicates, span }
= wc
;
918 visit_vec(predicates
, |predicate
| vis
.visit_where_predicate(predicate
));
919 vis
.visit_span(span
);
922 pub fn noop_visit_where_predicate
<T
: MutVisitor
>(pred
: &mut WherePredicate
, vis
: &mut T
) {
924 WherePredicate
::BoundPredicate(bp
) => {
925 let WhereBoundPredicate { span, bound_generic_params, bounded_ty, bounds }
= bp
;
926 vis
.visit_span(span
);
927 bound_generic_params
.flat_map_in_place(|param
| vis
.flat_map_generic_param(param
));
928 vis
.visit_ty(bounded_ty
);
929 visit_vec(bounds
, |bound
| vis
.visit_param_bound(bound
));
931 WherePredicate
::RegionPredicate(rp
) => {
932 let WhereRegionPredicate { span, lifetime, bounds }
= rp
;
933 vis
.visit_span(span
);
934 noop_visit_lifetime(lifetime
, vis
);
935 visit_vec(bounds
, |bound
| noop_visit_param_bound(bound
, vis
));
937 WherePredicate
::EqPredicate(ep
) => {
938 let WhereEqPredicate { span, lhs_ty, rhs_ty }
= ep
;
939 vis
.visit_span(span
);
940 vis
.visit_ty(lhs_ty
);
941 vis
.visit_ty(rhs_ty
);
946 pub fn noop_visit_variant_data
<T
: MutVisitor
>(vdata
: &mut VariantData
, vis
: &mut T
) {
948 VariantData
::Struct(fields
, ..) => {
949 fields
.flat_map_in_place(|field
| vis
.flat_map_field_def(field
));
951 VariantData
::Tuple(fields
, id
) => {
952 fields
.flat_map_in_place(|field
| vis
.flat_map_field_def(field
));
955 VariantData
::Unit(id
) => vis
.visit_id(id
),
959 pub fn noop_visit_trait_ref
<T
: MutVisitor
>(TraitRef { path, ref_id }
: &mut TraitRef
, vis
: &mut T
) {
960 vis
.visit_path(path
);
961 vis
.visit_id(ref_id
);
964 pub fn noop_visit_poly_trait_ref
<T
: MutVisitor
>(p
: &mut PolyTraitRef
, vis
: &mut T
) {
965 let PolyTraitRef { bound_generic_params, trait_ref, span }
= p
;
966 bound_generic_params
.flat_map_in_place(|param
| vis
.flat_map_generic_param(param
));
967 vis
.visit_trait_ref(trait_ref
);
968 vis
.visit_span(span
);
971 pub fn noop_flat_map_field_def
<T
: MutVisitor
>(
974 ) -> SmallVec
<[FieldDef
; 1]> {
975 let FieldDef { span, ident, vis, id, ty, attrs, is_placeholder: _ }
= &mut fd
;
976 visitor
.visit_span(span
);
977 visit_opt(ident
, |ident
| visitor
.visit_ident(ident
));
978 visitor
.visit_vis(vis
);
979 visitor
.visit_id(id
);
980 visitor
.visit_ty(ty
);
981 visit_attrs(attrs
, visitor
);
985 pub fn noop_flat_map_expr_field
<T
: MutVisitor
>(
988 ) -> SmallVec
<[ExprField
; 1]> {
989 let ExprField { ident, expr, span, is_shorthand: _, attrs, id, is_placeholder: _ }
= &mut f
;
990 vis
.visit_ident(ident
);
991 vis
.visit_expr(expr
);
993 vis
.visit_span(span
);
994 visit_attrs(attrs
, vis
);
998 pub fn noop_visit_mt
<T
: MutVisitor
>(MutTy { ty, mutbl: _ }
: &mut MutTy
, vis
: &mut T
) {
1002 pub fn noop_visit_block
<T
: MutVisitor
>(block
: &mut P
<Block
>, vis
: &mut T
) {
1003 let Block { id, stmts, rules: _, span, tokens, could_be_bare_literal: _ }
= block
.deref_mut();
1005 stmts
.flat_map_in_place(|stmt
| vis
.flat_map_stmt(stmt
));
1006 vis
.visit_span(span
);
1007 visit_lazy_tts(tokens
, vis
);
1010 pub fn noop_visit_item_kind
<T
: MutVisitor
>(kind
: &mut ItemKind
, vis
: &mut T
) {
1012 ItemKind
::ExternCrate(_orig_name
) => {}
1013 ItemKind
::Use(use_tree
) => vis
.visit_use_tree(use_tree
),
1014 ItemKind
::Static(ty
, _
, expr
) => {
1016 visit_opt(expr
, |expr
| vis
.visit_expr(expr
));
1018 ItemKind
::Const(defaultness
, ty
, expr
) => {
1019 visit_defaultness(defaultness
, vis
);
1021 visit_opt(expr
, |expr
| vis
.visit_expr(expr
));
1023 ItemKind
::Fn(box Fn { defaultness, generics, sig, body }
) => {
1024 visit_defaultness(defaultness
, vis
);
1025 visit_fn_sig(sig
, vis
);
1026 vis
.visit_generics(generics
);
1027 visit_opt(body
, |body
| vis
.visit_block(body
));
1029 ItemKind
::Mod(unsafety
, mod_kind
) => {
1030 visit_unsafety(unsafety
, vis
);
1032 ModKind
::Loaded(items
, _inline
, ModSpans { inner_span, inject_use_span }
) => {
1033 vis
.visit_span(inner_span
);
1034 vis
.visit_span(inject_use_span
);
1035 items
.flat_map_in_place(|item
| vis
.flat_map_item(item
));
1037 ModKind
::Unloaded
=> {}
1040 ItemKind
::ForeignMod(nm
) => vis
.visit_foreign_mod(nm
),
1041 ItemKind
::GlobalAsm(asm
) => vis
.visit_inline_asm(asm
),
1042 ItemKind
::TyAlias(box TyAlias
{
1043 defaultness
, generics
, where_clauses
, bounds
, ty
, ..
1045 visit_defaultness(defaultness
, vis
);
1046 vis
.visit_generics(generics
);
1047 vis
.visit_span(&mut where_clauses
.0.1);
1048 vis
.visit_span(&mut where_clauses
.1.1);
1049 visit_bounds(bounds
, vis
);
1050 visit_opt(ty
, |ty
| vis
.visit_ty(ty
));
1052 ItemKind
::Enum(EnumDef { variants }
, generics
) => {
1053 variants
.flat_map_in_place(|variant
| vis
.flat_map_variant(variant
));
1054 vis
.visit_generics(generics
);
1056 ItemKind
::Struct(variant_data
, generics
) | ItemKind
::Union(variant_data
, generics
) => {
1057 vis
.visit_variant_data(variant_data
);
1058 vis
.visit_generics(generics
);
1060 ItemKind
::Impl(box Impl
{
1070 visit_defaultness(defaultness
, vis
);
1071 visit_unsafety(unsafety
, vis
);
1072 vis
.visit_generics(generics
);
1073 visit_constness(constness
, vis
);
1074 visit_polarity(polarity
, vis
);
1075 visit_opt(of_trait
, |trait_ref
| vis
.visit_trait_ref(trait_ref
));
1076 vis
.visit_ty(self_ty
);
1077 items
.flat_map_in_place(|item
| vis
.flat_map_impl_item(item
));
1079 ItemKind
::Trait(box Trait { unsafety, is_auto: _, generics, bounds, items }
) => {
1080 visit_unsafety(unsafety
, vis
);
1081 vis
.visit_generics(generics
);
1082 visit_bounds(bounds
, vis
);
1083 items
.flat_map_in_place(|item
| vis
.flat_map_trait_item(item
));
1085 ItemKind
::TraitAlias(generics
, bounds
) => {
1086 vis
.visit_generics(generics
);
1087 visit_bounds(bounds
, vis
);
1089 ItemKind
::MacCall(m
) => vis
.visit_mac_call(m
),
1090 ItemKind
::MacroDef(def
) => vis
.visit_macro_def(def
),
1094 pub fn noop_flat_map_assoc_item
<T
: MutVisitor
>(
1095 mut item
: P
<AssocItem
>,
1097 ) -> SmallVec
<[P
<AssocItem
>; 1]> {
1098 let Item { id, ident, vis, attrs, kind, span, tokens }
= item
.deref_mut();
1099 visitor
.visit_id(id
);
1100 visitor
.visit_ident(ident
);
1101 visitor
.visit_vis(vis
);
1102 visit_attrs(attrs
, visitor
);
1104 AssocItemKind
::Const(defaultness
, ty
, expr
) => {
1105 visit_defaultness(defaultness
, visitor
);
1106 visitor
.visit_ty(ty
);
1107 visit_opt(expr
, |expr
| visitor
.visit_expr(expr
));
1109 AssocItemKind
::Fn(box Fn { defaultness, generics, sig, body }
) => {
1110 visit_defaultness(defaultness
, visitor
);
1111 visitor
.visit_generics(generics
);
1112 visit_fn_sig(sig
, visitor
);
1113 visit_opt(body
, |body
| visitor
.visit_block(body
));
1115 AssocItemKind
::Type(box TyAlias
{
1123 visit_defaultness(defaultness
, visitor
);
1124 visitor
.visit_generics(generics
);
1125 visitor
.visit_span(&mut where_clauses
.0.1);
1126 visitor
.visit_span(&mut where_clauses
.1.1);
1127 visit_bounds(bounds
, visitor
);
1128 visit_opt(ty
, |ty
| visitor
.visit_ty(ty
));
1130 AssocItemKind
::MacCall(mac
) => visitor
.visit_mac_call(mac
),
1132 visitor
.visit_span(span
);
1133 visit_lazy_tts(tokens
, visitor
);
1137 pub fn noop_visit_fn_header
<T
: MutVisitor
>(header
: &mut FnHeader
, vis
: &mut T
) {
1138 let FnHeader { unsafety, asyncness, constness, ext: _ }
= header
;
1139 visit_constness(constness
, vis
);
1140 vis
.visit_asyncness(asyncness
);
1141 visit_unsafety(unsafety
, vis
);
1144 pub fn noop_visit_crate
<T
: MutVisitor
>(krate
: &mut Crate
, vis
: &mut T
) {
1145 let Crate { attrs, items, spans, id, is_placeholder: _ }
= krate
;
1147 visit_attrs(attrs
, vis
);
1148 items
.flat_map_in_place(|item
| vis
.flat_map_item(item
));
1149 let ModSpans { inner_span, inject_use_span }
= spans
;
1150 vis
.visit_span(inner_span
);
1151 vis
.visit_span(inject_use_span
);
1154 // Mutates one item into possibly many items.
1155 pub fn noop_flat_map_item
<T
: MutVisitor
>(
1158 ) -> SmallVec
<[P
<Item
>; 1]> {
1159 let Item { ident, attrs, id, kind, vis, span, tokens }
= item
.deref_mut();
1160 visitor
.visit_ident(ident
);
1161 visit_attrs(attrs
, visitor
);
1162 visitor
.visit_id(id
);
1163 visitor
.visit_item_kind(kind
);
1164 visitor
.visit_vis(vis
);
1165 visitor
.visit_span(span
);
1166 visit_lazy_tts(tokens
, visitor
);
1171 pub fn noop_flat_map_foreign_item
<T
: MutVisitor
>(
1172 mut item
: P
<ForeignItem
>,
1174 ) -> SmallVec
<[P
<ForeignItem
>; 1]> {
1175 let Item { ident, attrs, id, kind, vis, span, tokens }
= item
.deref_mut();
1176 visitor
.visit_id(id
);
1177 visitor
.visit_ident(ident
);
1178 visitor
.visit_vis(vis
);
1179 visit_attrs(attrs
, visitor
);
1181 ForeignItemKind
::Static(ty
, _
, expr
) => {
1182 visitor
.visit_ty(ty
);
1183 visit_opt(expr
, |expr
| visitor
.visit_expr(expr
));
1185 ForeignItemKind
::Fn(box Fn { defaultness, generics, sig, body }
) => {
1186 visit_defaultness(defaultness
, visitor
);
1187 visitor
.visit_generics(generics
);
1188 visit_fn_sig(sig
, visitor
);
1189 visit_opt(body
, |body
| visitor
.visit_block(body
));
1191 ForeignItemKind
::TyAlias(box TyAlias
{
1199 visit_defaultness(defaultness
, visitor
);
1200 visitor
.visit_generics(generics
);
1201 visitor
.visit_span(&mut where_clauses
.0.1);
1202 visitor
.visit_span(&mut where_clauses
.1.1);
1203 visit_bounds(bounds
, visitor
);
1204 visit_opt(ty
, |ty
| visitor
.visit_ty(ty
));
1206 ForeignItemKind
::MacCall(mac
) => visitor
.visit_mac_call(mac
),
1208 visitor
.visit_span(span
);
1209 visit_lazy_tts(tokens
, visitor
);
1213 pub fn noop_visit_pat
<T
: MutVisitor
>(pat
: &mut P
<Pat
>, vis
: &mut T
) {
1214 let Pat { id, kind, span, tokens }
= pat
.deref_mut();
1217 PatKind
::Wild
| PatKind
::Rest
=> {}
1218 PatKind
::Ident(_binding_mode
, ident
, sub
) => {
1219 vis
.visit_ident(ident
);
1220 visit_opt(sub
, |sub
| vis
.visit_pat(sub
));
1222 PatKind
::Lit(e
) => vis
.visit_expr(e
),
1223 PatKind
::TupleStruct(qself
, path
, elems
) => {
1224 vis
.visit_qself(qself
);
1225 vis
.visit_path(path
);
1226 visit_vec(elems
, |elem
| vis
.visit_pat(elem
));
1228 PatKind
::Path(qself
, path
) => {
1229 vis
.visit_qself(qself
);
1230 vis
.visit_path(path
);
1232 PatKind
::Struct(qself
, path
, fields
, _etc
) => {
1233 vis
.visit_qself(qself
);
1234 vis
.visit_path(path
);
1235 fields
.flat_map_in_place(|field
| vis
.flat_map_pat_field(field
));
1237 PatKind
::Box(inner
) => vis
.visit_pat(inner
),
1238 PatKind
::Ref(inner
, _mutbl
) => vis
.visit_pat(inner
),
1239 PatKind
::Range(e1
, e2
, Spanned { span: _, node: _ }
) => {
1240 visit_opt(e1
, |e
| vis
.visit_expr(e
));
1241 visit_opt(e2
, |e
| vis
.visit_expr(e
));
1242 vis
.visit_span(span
);
1244 PatKind
::Tuple(elems
) | PatKind
::Slice(elems
) | PatKind
::Or(elems
) => {
1245 visit_vec(elems
, |elem
| vis
.visit_pat(elem
))
1247 PatKind
::Paren(inner
) => vis
.visit_pat(inner
),
1248 PatKind
::MacCall(mac
) => vis
.visit_mac_call(mac
),
1250 vis
.visit_span(span
);
1251 visit_lazy_tts(tokens
, vis
);
1254 pub fn noop_visit_anon_const
<T
: MutVisitor
>(AnonConst { id, value }
: &mut AnonConst
, vis
: &mut T
) {
1256 vis
.visit_expr(value
);
1259 pub fn noop_visit_inline_asm
<T
: MutVisitor
>(asm
: &mut InlineAsm
, vis
: &mut T
) {
1260 for (op
, _
) in &mut asm
.operands
{
1262 InlineAsmOperand
::In { expr, .. }
1263 | InlineAsmOperand
::Out { expr: Some(expr), .. }
1264 | InlineAsmOperand
::InOut { expr, .. }
=> vis
.visit_expr(expr
),
1265 InlineAsmOperand
::Out { expr: None, .. }
=> {}
1266 InlineAsmOperand
::SplitInOut { in_expr, out_expr, .. }
=> {
1267 vis
.visit_expr(in_expr
);
1268 if let Some(out_expr
) = out_expr
{
1269 vis
.visit_expr(out_expr
);
1272 InlineAsmOperand
::Const { anon_const }
=> vis
.visit_anon_const(anon_const
),
1273 InlineAsmOperand
::Sym { sym }
=> vis
.visit_inline_asm_sym(sym
),
1278 pub fn noop_visit_inline_asm_sym
<T
: MutVisitor
>(
1279 InlineAsmSym { id, qself, path }
: &mut InlineAsmSym
,
1283 vis
.visit_qself(qself
);
1284 vis
.visit_path(path
);
1287 pub fn noop_visit_expr
<T
: MutVisitor
>(
1288 Expr { kind, id, span, attrs, tokens }
: &mut Expr
,
1292 ExprKind
::Box(expr
) => vis
.visit_expr(expr
),
1293 ExprKind
::Array(exprs
) => visit_exprs(exprs
, vis
),
1294 ExprKind
::ConstBlock(anon_const
) => {
1295 vis
.visit_anon_const(anon_const
);
1297 ExprKind
::Repeat(expr
, count
) => {
1298 vis
.visit_expr(expr
);
1299 vis
.visit_anon_const(count
);
1301 ExprKind
::Tup(exprs
) => visit_exprs(exprs
, vis
),
1302 ExprKind
::Call(f
, args
) => {
1304 visit_exprs(args
, vis
);
1306 ExprKind
::MethodCall(box MethodCall
{
1307 seg
: PathSegment { ident, id, args: seg_args }
,
1312 vis
.visit_ident(ident
);
1314 visit_opt(seg_args
, |args
| vis
.visit_generic_args(args
));
1315 vis
.visit_method_receiver_expr(receiver
);
1316 visit_exprs(call_args
, vis
);
1317 vis
.visit_span(span
);
1319 ExprKind
::Binary(_binop
, lhs
, rhs
) => {
1320 vis
.visit_expr(lhs
);
1321 vis
.visit_expr(rhs
);
1323 ExprKind
::Unary(_unop
, ohs
) => vis
.visit_expr(ohs
),
1324 ExprKind
::Cast(expr
, ty
) => {
1325 vis
.visit_expr(expr
);
1328 ExprKind
::Type(expr
, ty
) => {
1329 vis
.visit_expr(expr
);
1332 ExprKind
::AddrOf(_
, _
, ohs
) => vis
.visit_expr(ohs
),
1333 ExprKind
::Let(pat
, scrutinee
, _
) => {
1335 vis
.visit_expr(scrutinee
);
1337 ExprKind
::If(cond
, tr
, fl
) => {
1338 vis
.visit_expr(cond
);
1339 vis
.visit_block(tr
);
1340 visit_opt(fl
, |fl
| vis
.visit_expr(fl
));
1342 ExprKind
::While(cond
, body
, label
) => {
1343 vis
.visit_expr(cond
);
1344 vis
.visit_block(body
);
1345 visit_opt(label
, |label
| vis
.visit_label(label
));
1347 ExprKind
::ForLoop(pat
, iter
, body
, label
) => {
1349 vis
.visit_expr(iter
);
1350 vis
.visit_block(body
);
1351 visit_opt(label
, |label
| vis
.visit_label(label
));
1353 ExprKind
::Loop(body
, label
, span
) => {
1354 vis
.visit_block(body
);
1355 visit_opt(label
, |label
| vis
.visit_label(label
));
1356 vis
.visit_span(span
);
1358 ExprKind
::Match(expr
, arms
) => {
1359 vis
.visit_expr(expr
);
1360 arms
.flat_map_in_place(|arm
| vis
.flat_map_arm(arm
));
1362 ExprKind
::Closure(box Closure
{
1372 vis
.visit_closure_binder(binder
);
1373 vis
.visit_asyncness(asyncness
);
1374 vis
.visit_fn_decl(fn_decl
);
1375 vis
.visit_expr(body
);
1376 vis
.visit_span(fn_decl_span
);
1378 ExprKind
::Block(blk
, label
) => {
1379 vis
.visit_block(blk
);
1380 visit_opt(label
, |label
| vis
.visit_label(label
));
1382 ExprKind
::Async(_capture_by
, node_id
, body
) => {
1383 vis
.visit_id(node_id
);
1384 vis
.visit_block(body
);
1386 ExprKind
::Await(expr
) => vis
.visit_expr(expr
),
1387 ExprKind
::Assign(el
, er
, _
) => {
1391 ExprKind
::AssignOp(_op
, el
, er
) => {
1395 ExprKind
::Field(el
, ident
) => {
1397 vis
.visit_ident(ident
);
1399 ExprKind
::Index(el
, er
) => {
1403 ExprKind
::Range(e1
, e2
, _lim
) => {
1404 visit_opt(e1
, |e1
| vis
.visit_expr(e1
));
1405 visit_opt(e2
, |e2
| vis
.visit_expr(e2
));
1407 ExprKind
::Underscore
=> {}
1408 ExprKind
::Path(qself
, path
) => {
1409 vis
.visit_qself(qself
);
1410 vis
.visit_path(path
);
1412 ExprKind
::Break(label
, expr
) => {
1413 visit_opt(label
, |label
| vis
.visit_label(label
));
1414 visit_opt(expr
, |expr
| vis
.visit_expr(expr
));
1416 ExprKind
::Continue(label
) => {
1417 visit_opt(label
, |label
| vis
.visit_label(label
));
1419 ExprKind
::Ret(expr
) => {
1420 visit_opt(expr
, |expr
| vis
.visit_expr(expr
));
1422 ExprKind
::Yeet(expr
) => {
1423 visit_opt(expr
, |expr
| vis
.visit_expr(expr
));
1425 ExprKind
::InlineAsm(asm
) => vis
.visit_inline_asm(asm
),
1426 ExprKind
::MacCall(mac
) => vis
.visit_mac_call(mac
),
1427 ExprKind
::Struct(se
) => {
1428 let StructExpr { qself, path, fields, rest }
= se
.deref_mut();
1429 vis
.visit_qself(qself
);
1430 vis
.visit_path(path
);
1431 fields
.flat_map_in_place(|field
| vis
.flat_map_expr_field(field
));
1433 StructRest
::Base(expr
) => vis
.visit_expr(expr
),
1434 StructRest
::Rest(_span
) => {}
1435 StructRest
::None
=> {}
1438 ExprKind
::Paren(expr
) => {
1439 vis
.visit_expr(expr
);
1441 ExprKind
::Yield(expr
) => {
1442 visit_opt(expr
, |expr
| vis
.visit_expr(expr
));
1444 ExprKind
::Try(expr
) => vis
.visit_expr(expr
),
1445 ExprKind
::TryBlock(body
) => vis
.visit_block(body
),
1446 ExprKind
::Lit(_
) | ExprKind
::IncludedBytes(..) | ExprKind
::Err
=> {}
1449 vis
.visit_span(span
);
1450 visit_attrs(attrs
, vis
);
1451 visit_lazy_tts(tokens
, vis
);
1454 pub fn noop_filter_map_expr
<T
: MutVisitor
>(mut e
: P
<Expr
>, vis
: &mut T
) -> Option
<P
<Expr
>> {
1456 vis
.visit_expr(&mut e
);
1461 pub fn noop_flat_map_stmt
<T
: MutVisitor
>(
1462 Stmt { kind, mut span, mut id }
: Stmt
,
1464 ) -> SmallVec
<[Stmt
; 1]> {
1465 vis
.visit_id(&mut id
);
1466 vis
.visit_span(&mut span
);
1467 let stmts
: SmallVec
<_
> = noop_flat_map_stmt_kind(kind
, vis
)
1469 .map(|kind
| Stmt { id, kind, span }
)
1471 if stmts
.len() > 1 {
1473 "cloning statement `NodeId`s is prohibited by default, \
1474 the visitor should implement custom statement visiting"
1480 pub fn noop_flat_map_stmt_kind
<T
: MutVisitor
>(
1483 ) -> SmallVec
<[StmtKind
; 1]> {
1485 StmtKind
::Local(mut local
) => smallvec
![StmtKind
::Local({
1486 vis
.visit_local(&mut local
);
1489 StmtKind
::Item(item
) => vis
.flat_map_item(item
).into_iter().map(StmtKind
::Item
).collect(),
1490 StmtKind
::Expr(expr
) => vis
.filter_map_expr(expr
).into_iter().map(StmtKind
::Expr
).collect(),
1491 StmtKind
::Semi(expr
) => vis
.filter_map_expr(expr
).into_iter().map(StmtKind
::Semi
).collect(),
1492 StmtKind
::Empty
=> smallvec
![StmtKind
::Empty
],
1493 StmtKind
::MacCall(mut mac
) => {
1494 let MacCallStmt { mac: mac_, style: _, attrs, tokens }
= mac
.deref_mut();
1495 vis
.visit_mac_call(mac_
);
1496 visit_attrs(attrs
, vis
);
1497 visit_lazy_tts(tokens
, vis
);
1498 smallvec
![StmtKind
::MacCall(mac
)]
1503 pub fn noop_visit_vis
<T
: MutVisitor
>(visibility
: &mut Visibility
, vis
: &mut T
) {
1504 match &mut visibility
.kind
{
1505 VisibilityKind
::Public
| VisibilityKind
::Inherited
=> {}
1506 VisibilityKind
::Restricted { path, id, shorthand: _ }
=> {
1507 vis
.visit_path(path
);
1511 vis
.visit_span(&mut visibility
.span
);
1514 /// Some value for the AST node that is valid but possibly meaningless.
1515 pub trait DummyAstNode
{
1519 impl<T
> DummyAstNode
for Option
<T
> {
1520 fn dummy() -> Self {
1525 impl<T
: DummyAstNode
+ '
static> DummyAstNode
for P
<T
> {
1526 fn dummy() -> Self {
1527 P(DummyAstNode
::dummy())
1531 impl DummyAstNode
for Item
{
1532 fn dummy() -> Self {
1534 attrs
: Default
::default(),
1536 span
: Default
::default(),
1538 kind
: VisibilityKind
::Public
,
1539 span
: Default
::default(),
1540 tokens
: Default
::default(),
1542 ident
: Ident
::empty(),
1543 kind
: ItemKind
::ExternCrate(None
),
1544 tokens
: Default
::default(),
1549 impl DummyAstNode
for Expr
{
1550 fn dummy() -> Self {
1553 kind
: ExprKind
::Err
,
1554 span
: Default
::default(),
1555 attrs
: Default
::default(),
1556 tokens
: Default
::default(),
1561 impl DummyAstNode
for Ty
{
1562 fn dummy() -> Self {
1566 span
: Default
::default(),
1567 tokens
: Default
::default(),
1572 impl DummyAstNode
for Pat
{
1573 fn dummy() -> Self {
1576 kind
: PatKind
::Wild
,
1577 span
: Default
::default(),
1578 tokens
: Default
::default(),
1583 impl DummyAstNode
for Stmt
{
1584 fn dummy() -> Self {
1585 Stmt { id: DUMMY_NODE_ID, kind: StmtKind::Empty, span: Default::default() }
1589 impl DummyAstNode
for Block
{
1590 fn dummy() -> Self {
1592 stmts
: Default
::default(),
1594 rules
: BlockCheckMode
::Default
,
1595 span
: Default
::default(),
1596 tokens
: Default
::default(),
1597 could_be_bare_literal
: Default
::default(),
1602 impl DummyAstNode
for Crate
{
1603 fn dummy() -> Self {
1605 attrs
: Default
::default(),
1606 items
: Default
::default(),
1607 spans
: Default
::default(),
1609 is_placeholder
: Default
::default(),
1614 impl<N
: DummyAstNode
, T
: DummyAstNode
> DummyAstNode
for crate::ast_traits
::AstNodeWrapper
<N
, T
> {
1615 fn dummy() -> Self {
1616 crate::ast_traits
::AstNodeWrapper
::new(N
::dummy(), T
::dummy())