|  | //! AST walker. Each overridden visit method has full control over what | 
|  | //! happens with its node, it can do its own traversal of the node's children, | 
|  | //! call `visit::walk_*` to apply the default traversal algorithm, or prevent | 
|  | //! deeper traversal by doing nothing. | 
|  | //! | 
|  | //! Note: it is an important invariant that the default visitor walks the body | 
|  | //! of a function in "execution order" (more concretely, reverse post-order | 
|  | //! with respect to the CFG implied by the AST), meaning that if AST node A may | 
|  | //! execute before AST node B, then A is visited first. The borrow checker in | 
|  | //! particular relies on this property. | 
|  | //! | 
|  | //! Note: walking an AST before macro expansion is probably a bad idea. For | 
|  | //! instance, a walker looking for item names in a module will miss all of | 
|  | //! those that are created by the expansion of a macro. | 
|  |  | 
|  | pub use rustc_ast_ir::visit::VisitorResult; | 
|  | pub use rustc_ast_ir::{try_visit, visit_opt, walk_list, walk_visitable_list}; | 
|  | use rustc_span::source_map::Spanned; | 
|  | use rustc_span::{Ident, Span, Symbol}; | 
|  | use thin_vec::ThinVec; | 
|  |  | 
|  | use crate::ast::*; | 
|  | use crate::tokenstream::DelimSpan; | 
|  |  | 
|  | #[derive(Copy, Clone, Debug, PartialEq)] | 
|  | pub enum AssocCtxt { | 
|  | Trait, | 
|  | Impl { of_trait: bool }, | 
|  | } | 
|  |  | 
|  | #[derive(Copy, Clone, Debug, PartialEq)] | 
|  | pub enum FnCtxt { | 
|  | Free, | 
|  | Foreign, | 
|  | Assoc(AssocCtxt), | 
|  | } | 
|  |  | 
|  | #[derive(Copy, Clone, Debug)] | 
|  | pub enum BoundKind { | 
|  | /// Trait bounds in generics bounds and type/trait alias. | 
|  | /// E.g., `<T: Bound>`, `type A: Bound`, or `where T: Bound`. | 
|  | Bound, | 
|  |  | 
|  | /// Trait bounds in `impl` type. | 
|  | /// E.g., `type Foo = impl Bound1 + Bound2 + Bound3`. | 
|  | Impl, | 
|  |  | 
|  | /// Trait bounds in trait object type. | 
|  | /// E.g., `dyn Bound1 + Bound2 + Bound3`. | 
|  | TraitObject, | 
|  |  | 
|  | /// Super traits of a trait. | 
|  | /// E.g., `trait A: B` | 
|  | SuperTraits, | 
|  | } | 
|  | impl BoundKind { | 
|  | pub fn descr(self) -> &'static str { | 
|  | match self { | 
|  | BoundKind::Bound => "bounds", | 
|  | BoundKind::Impl => "`impl Trait`", | 
|  | BoundKind::TraitObject => "`dyn` trait object bounds", | 
|  | BoundKind::SuperTraits => "supertrait bounds", | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | #[derive(Copy, Clone, Debug)] | 
|  | pub enum LifetimeCtxt { | 
|  | /// Appears in a reference type. | 
|  | Ref, | 
|  | /// Appears as a bound on a type or another lifetime. | 
|  | Bound, | 
|  | /// Appears as a generic argument. | 
|  | GenericArg, | 
|  | } | 
|  |  | 
|  | pub(crate) trait Visitable<'a, V: Visitor<'a>> { | 
|  | type Extra: Copy; | 
|  |  | 
|  | #[must_use] | 
|  | fn visit(&'a self, visitor: &mut V, extra: Self::Extra) -> V::Result; | 
|  | } | 
|  |  | 
|  | impl<'a, V: Visitor<'a>, T: ?Sized> Visitable<'a, V> for Box<T> | 
|  | where | 
|  | T: Visitable<'a, V>, | 
|  | { | 
|  | type Extra = T::Extra; | 
|  | fn visit(&'a self, visitor: &mut V, extra: Self::Extra) -> V::Result { | 
|  | (**self).visit(visitor, extra) | 
|  | } | 
|  | } | 
|  |  | 
|  | impl<'a, V: Visitor<'a>, T> Visitable<'a, V> for Option<T> | 
|  | where | 
|  | T: Visitable<'a, V>, | 
|  | { | 
|  | type Extra = T::Extra; | 
|  | fn visit(&'a self, visitor: &mut V, extra: Self::Extra) -> V::Result { | 
|  | if let Some(this) = self { | 
|  | try_visit!(this.visit(visitor, extra)); | 
|  | } | 
|  | V::Result::output() | 
|  | } | 
|  | } | 
|  |  | 
|  | impl<'a, V: Visitor<'a>, T> Visitable<'a, V> for Spanned<T> | 
|  | where | 
|  | T: Visitable<'a, V>, | 
|  | { | 
|  | type Extra = T::Extra; | 
|  | fn visit(&'a self, visitor: &mut V, extra: Self::Extra) -> V::Result { | 
|  | let Spanned { span: _, node } = self; | 
|  | node.visit(visitor, extra) | 
|  | } | 
|  | } | 
|  |  | 
|  | impl<'a, V: Visitor<'a>, T> Visitable<'a, V> for [T] | 
|  | where | 
|  | T: Visitable<'a, V>, | 
|  | { | 
|  | type Extra = T::Extra; | 
|  | fn visit(&'a self, visitor: &mut V, extra: Self::Extra) -> V::Result { | 
|  | for item in self { | 
|  | try_visit!(item.visit(visitor, extra)); | 
|  | } | 
|  | V::Result::output() | 
|  | } | 
|  | } | 
|  |  | 
|  | impl<'a, V: Visitor<'a>, T> Visitable<'a, V> for Vec<T> | 
|  | where | 
|  | T: Visitable<'a, V>, | 
|  | { | 
|  | type Extra = T::Extra; | 
|  | fn visit(&'a self, visitor: &mut V, extra: Self::Extra) -> V::Result { | 
|  | for item in self { | 
|  | try_visit!(item.visit(visitor, extra)); | 
|  | } | 
|  | V::Result::output() | 
|  | } | 
|  | } | 
|  |  | 
|  | impl<'a, V: Visitor<'a>, T> Visitable<'a, V> for (T,) | 
|  | where | 
|  | T: Visitable<'a, V>, | 
|  | { | 
|  | type Extra = T::Extra; | 
|  | fn visit(&'a self, visitor: &mut V, extra: Self::Extra) -> V::Result { | 
|  | self.0.visit(visitor, extra) | 
|  | } | 
|  | } | 
|  |  | 
|  | impl<'a, V: Visitor<'a>, T1, T2> Visitable<'a, V> for (T1, T2) | 
|  | where | 
|  | T1: Visitable<'a, V, Extra = ()>, | 
|  | T2: Visitable<'a, V, Extra = ()>, | 
|  | { | 
|  | type Extra = (); | 
|  | fn visit(&'a self, visitor: &mut V, extra: Self::Extra) -> V::Result { | 
|  | try_visit!(self.0.visit(visitor, extra)); | 
|  | try_visit!(self.1.visit(visitor, extra)); | 
|  | V::Result::output() | 
|  | } | 
|  | } | 
|  |  | 
|  | impl<'a, V: Visitor<'a>, T1, T2, T3> Visitable<'a, V> for (T1, T2, T3) | 
|  | where | 
|  | T1: Visitable<'a, V, Extra = ()>, | 
|  | T2: Visitable<'a, V, Extra = ()>, | 
|  | T3: Visitable<'a, V, Extra = ()>, | 
|  | { | 
|  | type Extra = (); | 
|  | fn visit(&'a self, visitor: &mut V, extra: Self::Extra) -> V::Result { | 
|  | try_visit!(self.0.visit(visitor, extra)); | 
|  | try_visit!(self.1.visit(visitor, extra)); | 
|  | try_visit!(self.2.visit(visitor, extra)); | 
|  | V::Result::output() | 
|  | } | 
|  | } | 
|  |  | 
|  | impl<'a, V: Visitor<'a>, T1, T2, T3, T4> Visitable<'a, V> for (T1, T2, T3, T4) | 
|  | where | 
|  | T1: Visitable<'a, V, Extra = ()>, | 
|  | T2: Visitable<'a, V, Extra = ()>, | 
|  | T3: Visitable<'a, V, Extra = ()>, | 
|  | T4: Visitable<'a, V, Extra = ()>, | 
|  | { | 
|  | type Extra = (); | 
|  | fn visit(&'a self, visitor: &mut V, extra: Self::Extra) -> V::Result { | 
|  | try_visit!(self.0.visit(visitor, extra)); | 
|  | try_visit!(self.1.visit(visitor, extra)); | 
|  | try_visit!(self.2.visit(visitor, extra)); | 
|  | try_visit!(self.3.visit(visitor, extra)); | 
|  | V::Result::output() | 
|  | } | 
|  | } | 
|  |  | 
|  | pub(crate) trait Walkable<'a, V: Visitor<'a>> { | 
|  | #[must_use] | 
|  | fn walk_ref(&'a self, visitor: &mut V) -> V::Result; | 
|  | } | 
|  |  | 
|  | macro_rules! visit_visitable { | 
|  | ($visitor:expr, $($expr:expr),* $(,)?) => {{ | 
|  | $(try_visit!(Visitable::visit($expr, $visitor, ()));)* | 
|  | }}; | 
|  | } | 
|  |  | 
|  | macro_rules! visit_visitable_with { | 
|  | ($visitor:expr, $expr:expr, $extra:expr $(,)?) => { | 
|  | try_visit!(Visitable::visit($expr, $visitor, $extra)) | 
|  | }; | 
|  | } | 
|  |  | 
|  | macro_rules! walk_walkable { | 
|  | ($visitor:expr, $expr:expr, ) => { | 
|  | Walkable::walk_ref($expr, $visitor) | 
|  | }; | 
|  | } | 
|  |  | 
|  | macro_rules! impl_visitable { | 
|  | (|&$lt:lifetime $self:ident: $self_ty:ty, | 
|  | $vis:ident: &mut $vis_ty:ident, | 
|  | $extra:ident: $extra_ty:ty| $block:block) => { | 
|  | #[allow(unused_parens, non_local_definitions)] | 
|  | impl<$lt, $vis_ty: Visitor<$lt>> Visitable<$lt, $vis_ty> for $self_ty { | 
|  | type Extra = $extra_ty; | 
|  | fn visit(&$lt $self, $vis: &mut $vis_ty, $extra: Self::Extra) -> V::Result { | 
|  | $block | 
|  | } | 
|  | } | 
|  | }; | 
|  | } | 
|  |  | 
|  | macro_rules! impl_walkable { | 
|  | ($(<$K:ident: $Kb:ident>)? |&$lt:lifetime $self:ident: $self_ty:ty, | 
|  | $vis:ident: &mut $vis_ty:ident| $block:block) => { | 
|  | #[allow(unused_parens, non_local_definitions)] | 
|  | impl<$($K: $Kb,)? $lt, $vis_ty: Visitor<$lt>> Walkable<$lt, $vis_ty> for $self_ty { | 
|  | fn walk_ref(&$lt $self, $vis: &mut $vis_ty) -> V::Result { | 
|  | $block | 
|  | } | 
|  | } | 
|  | }; | 
|  | } | 
|  |  | 
|  | macro_rules! impl_visitable_noop { | 
|  | (<$lt:lifetime> $($ty:ty,)*) => { | 
|  | $( | 
|  | impl_visitable!(|&$lt self: $ty, _vis: &mut V, _extra: ()| { | 
|  | V::Result::output() | 
|  | }); | 
|  | )* | 
|  | }; | 
|  | } | 
|  |  | 
|  | macro_rules! impl_visitable_list { | 
|  | (<$lt:lifetime> $($ty:ty,)*) => { | 
|  | $(impl<$lt, V: Visitor<$lt>, T> Visitable<$lt, V> for $ty | 
|  | where | 
|  | &$lt $ty: IntoIterator<Item = &$lt T>, | 
|  | T: $lt + Visitable<$lt, V>, | 
|  | { | 
|  | type Extra = <T as Visitable<$lt, V>>::Extra; | 
|  |  | 
|  | #[inline] | 
|  | fn visit(&$lt self, visitor: &mut V, extra: Self::Extra) -> V::Result { | 
|  | for i in self { | 
|  | try_visit!(i.visit(visitor, extra)); | 
|  | } | 
|  | V::Result::output() | 
|  | } | 
|  | })* | 
|  | }; | 
|  | } | 
|  |  | 
|  | macro_rules! impl_visitable_direct { | 
|  | (<$lt:lifetime> $($ty:ty,)*) => { | 
|  | $(impl_visitable!( | 
|  | |&$lt self: $ty, visitor: &mut V, _extra: ()| { | 
|  | Walkable::walk_ref(self, visitor) | 
|  | } | 
|  | );)* | 
|  | }; | 
|  | } | 
|  |  | 
|  | macro_rules! impl_visitable_calling_walkable { | 
|  | (<$lt:lifetime> | 
|  | $( fn $method:ident($ty:ty $(, $extra_name:ident: $extra_ty:ty)?); )* | 
|  | ) => { | 
|  | $(fn $method(&mut self, node: &$lt $ty $(, $extra_name:$extra_ty)?) -> Self::Result { | 
|  | impl_visitable!(|&$lt self: $ty, visitor: &mut V, extra: ($($extra_ty)?)| { | 
|  | let ($($extra_name)?) = extra; | 
|  | visitor.$method(self $(, $extra_name)?) | 
|  | }); | 
|  | walk_walkable!(self, node, ) | 
|  | })* | 
|  | }; | 
|  | } | 
|  |  | 
|  | macro_rules! define_named_walk { | 
|  | ($Visitor:ident<$lt:lifetime> | 
|  | $( pub fn $method:ident($ty:ty); )* | 
|  | ) => { | 
|  | $(pub fn $method<$lt, V: $Visitor<$lt>>(visitor: &mut V, node: &$lt $ty) -> V::Result { | 
|  | walk_walkable!(visitor, node,) | 
|  | })* | 
|  | }; | 
|  | } | 
|  |  | 
|  | #[macro_export] | 
|  | macro_rules! common_visitor_and_walkers { | 
|  | ($(($mut: ident))? $Visitor:ident$(<$lt:lifetime>)?) => { | 
|  | $(${ignore($lt)} | 
|  | #[derive(Copy, Clone)] | 
|  | )? | 
|  | #[derive(Debug)] | 
|  | pub enum FnKind<'a> { | 
|  | /// E.g., `fn foo()`, `fn foo(&self)`, or `extern "Abi" fn foo()`. | 
|  | Fn(FnCtxt, &'a $($mut)? Visibility, &'a $($mut)? Fn), | 
|  |  | 
|  | /// E.g., `|x, y| body`. | 
|  | Closure(&'a $($mut)? ClosureBinder, &'a $($mut)? Option<CoroutineKind>, &'a $($mut)? Box<FnDecl>, &'a $($mut)? Box<Expr>), | 
|  | } | 
|  |  | 
|  | impl<'a> FnKind<'a> { | 
|  | pub fn header(&'a $($mut)? self) -> Option<&'a $($mut)? FnHeader> { | 
|  | match *self { | 
|  | FnKind::Fn(_, _, Fn { sig, .. }) => Some(&$($mut)? sig.header), | 
|  | FnKind::Closure(..) => None, | 
|  | } | 
|  | } | 
|  |  | 
|  | pub fn ident(&'a $($mut)? self) -> Option<&'a $($mut)? Ident> { | 
|  | match self { | 
|  | FnKind::Fn(_, _, Fn { ident, .. }) => Some(ident), | 
|  | _ => None, | 
|  | } | 
|  | } | 
|  |  | 
|  | pub fn decl(&'a $($mut)? self) -> &'a $($mut)? FnDecl { | 
|  | match self { | 
|  | FnKind::Fn(_, _, Fn { sig, .. }) => &$($mut)? sig.decl, | 
|  | FnKind::Closure(_, _, decl, _) => decl, | 
|  | } | 
|  | } | 
|  |  | 
|  | pub fn ctxt(&self) -> Option<FnCtxt> { | 
|  | match self { | 
|  | FnKind::Fn(ctxt, ..) => Some(*ctxt), | 
|  | FnKind::Closure(..) => None, | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | // This macro generates `impl Visitable` and `impl MutVisitable` that do nothing. | 
|  | impl_visitable_noop!(<$($lt)? $($mut)?> | 
|  | AttrId, | 
|  | bool, | 
|  | rustc_span::ByteSymbol, | 
|  | char, | 
|  | crate::token::CommentKind, | 
|  | crate::token::Delimiter, | 
|  | crate::token::Lit, | 
|  | crate::token::LitKind, | 
|  | crate::tokenstream::LazyAttrTokenStream, | 
|  | crate::tokenstream::TokenStream, | 
|  | Movability, | 
|  | Mutability, | 
|  | Result<(), rustc_span::ErrorGuaranteed>, | 
|  | rustc_data_structures::fx::FxHashMap<Symbol, usize>, | 
|  | rustc_span::ErrorGuaranteed, | 
|  | std::borrow::Cow<'_, str>, | 
|  | Symbol, | 
|  | u8, | 
|  | usize, | 
|  | ); | 
|  | // `Span` is only a no-op for the non-mutable visitor. | 
|  | $(impl_visitable_noop!(<$lt> Span,);)? | 
|  |  | 
|  | // This macro generates `impl Visitable` and `impl MutVisitable` that simply iterate over | 
|  | // their contents. We do not use a generic impl for `ThinVec` because we want to allow | 
|  | // custom visits for the `MutVisitor`. | 
|  | impl_visitable_list!(<$($lt)? $($mut)?> | 
|  | ThinVec<AngleBracketedArg>, | 
|  | ThinVec<Attribute>, | 
|  | ThinVec<(Ident, Option<Ident>)>, | 
|  | ThinVec<(NodeId, Path)>, | 
|  | ThinVec<PathSegment>, | 
|  | ThinVec<PreciseCapturingArg>, | 
|  | ThinVec<Pat>, | 
|  | ThinVec<Box<Ty>>, | 
|  | ThinVec<TyPat>, | 
|  | ); | 
|  |  | 
|  | // This macro generates `impl Visitable` and `impl MutVisitable` that forward to `Walkable` | 
|  | // or `MutWalkable`. By default, all types that do not have a custom visit method in the | 
|  | // visitor should appear here. | 
|  | impl_visitable_direct!(<$($lt)? $($mut)?> | 
|  | AngleBracketedArg, | 
|  | AngleBracketedArgs, | 
|  | AsmMacro, | 
|  | AssignOpKind, | 
|  | AssocItemConstraintKind, | 
|  | AttrArgs, | 
|  | AttrItem, | 
|  | AttrKind, | 
|  | AttrStyle, | 
|  | FnPtrTy, | 
|  | BindingMode, | 
|  | GenBlockKind, | 
|  | RangeLimits, | 
|  | UnsafeBinderCastKind, | 
|  | BinOpKind, | 
|  | BlockCheckMode, | 
|  | BorrowKind, | 
|  | BoundAsyncness, | 
|  | BoundConstness, | 
|  | BoundPolarity, | 
|  | ByRef, | 
|  | Closure, | 
|  | Const, | 
|  | ConstItem, | 
|  | Defaultness, | 
|  | Delegation, | 
|  | DelegationMac, | 
|  | DelimArgs, | 
|  | DelimSpan, | 
|  | EnumDef, | 
|  | Extern, | 
|  | ForLoopKind, | 
|  | FormatArgPosition, | 
|  | FormatArgsPiece, | 
|  | FormatArgument, | 
|  | FormatArgumentKind, | 
|  | FormatArguments, | 
|  | FormatPlaceholder, | 
|  | GenericParamKind, | 
|  | Impl, | 
|  | ImplPolarity, | 
|  | Inline, | 
|  | InlineAsmOperand, | 
|  | InlineAsmRegOrRegClass, | 
|  | InlineAsmTemplatePiece, | 
|  | IsAuto, | 
|  | LocalKind, | 
|  | MacCallStmt, | 
|  | MacStmtStyle, | 
|  | MatchKind, | 
|  | MethodCall, | 
|  | ModKind, | 
|  | ModSpans, | 
|  | MutTy, | 
|  | NormalAttr, | 
|  | Parens, | 
|  | ParenthesizedArgs, | 
|  | PatFieldsRest, | 
|  | PatKind, | 
|  | RangeEnd, | 
|  | RangeSyntax, | 
|  | Recovered, | 
|  | Safety, | 
|  | StaticItem, | 
|  | StrLit, | 
|  | StrStyle, | 
|  | StructExpr, | 
|  | StructRest, | 
|  | Term, | 
|  | Trait, | 
|  | TraitBoundModifiers, | 
|  | TraitObjectSyntax, | 
|  | TyAlias, | 
|  | TyKind, | 
|  | TyPatKind, | 
|  | UnOp, | 
|  | UnsafeBinderTy, | 
|  | UnsafeSource, | 
|  | UseTreeKind, | 
|  | VisibilityKind, | 
|  | WhereBoundPredicate, | 
|  | WhereClause, | 
|  | WhereEqPredicate, | 
|  | WhereRegionPredicate, | 
|  | YieldKind, | 
|  | ); | 
|  |  | 
|  | /// Each method of this trait is a hook to be potentially | 
|  | /// overridden. Each method's default implementation recursively visits | 
|  | /// the substructure of the input via the corresponding `walk` method; | 
|  | #[doc = concat!(" e.g., the `visit_item` method by default calls `visit"$(, "_", stringify!($mut))?, "::walk_item`.")] | 
|  | /// | 
|  | /// If you want to ensure that your code handles every variant | 
|  | /// explicitly, you need to override each method. (And you also need | 
|  | /// to monitor future changes to this trait in case a new method with a | 
|  | /// new default implementation gets introduced.) | 
|  | /// | 
|  | /// Every `walk_*` method uses deconstruction to access fields of structs and | 
|  | /// enums. This will result in a compile error if a field is added, which makes | 
|  | /// it more likely the appropriate visit call will be added for it. | 
|  | pub trait $Visitor<$($lt)?> : Sized $(${ignore($mut)} + MutVisitorResult<Result = ()>)? { | 
|  | $( | 
|  | ${ignore($lt)} | 
|  | /// The result type of the `visit_*` methods. Can be either `()`, | 
|  | /// or `ControlFlow<T>`. | 
|  | type Result: VisitorResult = (); | 
|  | )? | 
|  |  | 
|  | // Methods in this trait have one of three forms, with the last two forms | 
|  | // only occurring on `MutVisitor`: | 
|  | // | 
|  | //   fn visit_t(&mut self, t: &mut T);                      // common | 
|  | //   fn flat_map_t(&mut self, t: T) -> SmallVec<[T; 1]>;    // rare | 
|  | //   fn filter_map_t(&mut self, t: T) -> Option<T>;         // rarest | 
|  | // | 
|  | // When writing these methods, it is better to use destructuring like this: | 
|  | // | 
|  | //   fn visit_abc(&mut self, ABC { a, b, c: _ }: &mut ABC) { | 
|  | //       visit_a(a); | 
|  | //       visit_b(b); | 
|  | //   } | 
|  | // | 
|  | // than to use field access like this: | 
|  | // | 
|  | //   fn visit_abc(&mut self, abc: &mut ABC) { | 
|  | //       visit_a(&mut abc.a); | 
|  | //       visit_b(&mut abc.b); | 
|  | //       // ignore abc.c | 
|  | //   } | 
|  | // | 
|  | // As well as being more concise, the former is explicit about which fields | 
|  | // are skipped. Furthermore, if a new field is added, the destructuring | 
|  | // version will cause a compile error, which is good. In comparison, the | 
|  | // field access version will continue working and it would be easy to | 
|  | // forget to add handling for it. | 
|  | fn visit_ident(&mut self, Ident { name: _, span }: &$($lt)? $($mut)? Ident) -> Self::Result { | 
|  | impl_visitable!(|&$($lt)? $($mut)? self: Ident, visitor: &mut V, _extra: ()| { | 
|  | visitor.visit_ident(self) | 
|  | }); | 
|  | visit_span(self, span) | 
|  | } | 
|  |  | 
|  | // This macro defines a custom visit method for each listed type. | 
|  | // It implements `impl Visitable` and `impl MutVisitable` to call those methods on the | 
|  | // visitor. | 
|  | impl_visitable_calling_walkable!(<$($lt)? $($mut)?> | 
|  | fn visit_anon_const(AnonConst); | 
|  | fn visit_arm(Arm); | 
|  | //fn visit_assoc_item(AssocItem, _ctxt: AssocCtxt); | 
|  | fn visit_assoc_item_constraint(AssocItemConstraint); | 
|  | fn visit_attribute(Attribute); | 
|  | fn visit_block(Block); | 
|  | //fn visit_nested_use_tree((UseTree, NodeId)); | 
|  | fn visit_capture_by(CaptureBy); | 
|  | fn visit_closure_binder(ClosureBinder); | 
|  | fn visit_contract(FnContract); | 
|  | fn visit_coroutine_kind(CoroutineKind); | 
|  | fn visit_crate(Crate); | 
|  | fn visit_expr(Expr); | 
|  | fn visit_expr_field(ExprField); | 
|  | fn visit_field_def(FieldDef); | 
|  | fn visit_fn_decl(FnDecl); | 
|  | fn visit_fn_header(FnHeader); | 
|  | fn visit_fn_ret_ty(FnRetTy); | 
|  | //fn visit_foreign_item(ForeignItem); | 
|  | fn visit_foreign_mod(ForeignMod); | 
|  | fn visit_format_args(FormatArgs); | 
|  | fn visit_generic_arg(GenericArg); | 
|  | fn visit_generic_args(GenericArgs); | 
|  | fn visit_generic_param(GenericParam); | 
|  | fn visit_generics(Generics); | 
|  | fn visit_inline_asm(InlineAsm); | 
|  | fn visit_inline_asm_sym(InlineAsmSym); | 
|  | //fn visit_item(Item); | 
|  | fn visit_label(Label); | 
|  | fn visit_lifetime(Lifetime, _ctxt: LifetimeCtxt); | 
|  | fn visit_local(Local); | 
|  | fn visit_mac_call(MacCall); | 
|  | fn visit_macro_def(MacroDef); | 
|  | fn visit_param_bound(GenericBound, _ctxt: BoundKind); | 
|  | fn visit_param(Param); | 
|  | fn visit_pat_field(PatField); | 
|  | fn visit_path(Path); | 
|  | fn visit_path_segment(PathSegment); | 
|  | fn visit_pat(Pat); | 
|  | fn visit_poly_trait_ref(PolyTraitRef); | 
|  | fn visit_precise_capturing_arg(PreciseCapturingArg); | 
|  | fn visit_qself(QSelf); | 
|  | fn visit_trait_ref(TraitRef); | 
|  | fn visit_ty_pat(TyPat); | 
|  | fn visit_ty(Ty); | 
|  | fn visit_use_tree(UseTree); | 
|  | fn visit_variant_data(VariantData); | 
|  | fn visit_variant(Variant); | 
|  | fn visit_vis(Visibility); | 
|  | fn visit_where_predicate_kind(WherePredicateKind); | 
|  | fn visit_where_predicate(WherePredicate); | 
|  | ); | 
|  |  | 
|  | // We want `Visitor` to take the `NodeId` by value. | 
|  | fn visit_id(&mut self, _id: $(&$mut)? NodeId) -> Self::Result { | 
|  | $(impl_visitable!( | 
|  | |&$lt self: NodeId, visitor: &mut V, _extra: ()| { | 
|  | visitor.visit_id(*self) | 
|  | } | 
|  | );)? | 
|  | $(impl_visitable!( | 
|  | |&$mut self: NodeId, visitor: &mut V, _extra: ()| { | 
|  | visitor.visit_id(self) | 
|  | } | 
|  | );)? | 
|  | Self::Result::output() | 
|  | } | 
|  |  | 
|  | /// This method is a hack to workaround unstable of `stmt_expr_attributes`. | 
|  | /// It can be removed once that feature is stabilized. | 
|  | fn visit_method_receiver_expr(&mut self, ex: &$($lt)? $($mut)? Expr) -> Self::Result { | 
|  | self.visit_expr(ex) | 
|  | } | 
|  |  | 
|  | fn visit_item(&mut self, item: &$($lt)? $($mut)? Item) -> Self::Result { | 
|  | impl_visitable!(|&$($lt)? $($mut)? self: Item, vis: &mut V, _extra: ()| { | 
|  | vis.visit_item(self) | 
|  | }); | 
|  | walk_item(self, item) | 
|  | } | 
|  |  | 
|  | fn visit_foreign_item(&mut self, item: &$($lt)? $($mut)? ForeignItem) -> Self::Result { | 
|  | impl_visitable!(|&$($lt)? $($mut)? self: ForeignItem, vis: &mut V, _extra: ()| { | 
|  | vis.visit_foreign_item(self) | 
|  | }); | 
|  | walk_item(self, item) | 
|  | } | 
|  |  | 
|  | fn visit_assoc_item(&mut self, item: &$($lt)? $($mut)? AssocItem, ctxt: AssocCtxt) -> Self::Result { | 
|  | impl_visitable!(|&$($lt)? $($mut)? self: AssocItem, vis: &mut V, ctxt: AssocCtxt| { | 
|  | vis.visit_assoc_item(self, ctxt) | 
|  | }); | 
|  | walk_assoc_item(self, item, ctxt) | 
|  | } | 
|  |  | 
|  | // for `MutVisitor`: `Span` and `NodeId` are mutated at the caller site. | 
|  | fn visit_fn( | 
|  | &mut self, | 
|  | fk: FnKind<$($lt)? $(${ignore($mut)} '_)?>, | 
|  | _: Span, | 
|  | _: NodeId | 
|  | ) -> Self::Result { | 
|  | walk_fn(self, fk) | 
|  | } | 
|  |  | 
|  | // (non-mut) `Visitor`-only methods | 
|  | $( | 
|  | fn visit_stmt(&mut self, s: &$lt Stmt) -> Self::Result { | 
|  | walk_stmt(self, s) | 
|  | } | 
|  |  | 
|  | fn visit_nested_use_tree(&mut self, use_tree: &$lt UseTree, id: NodeId) -> Self::Result { | 
|  | try_visit!(self.visit_id(id)); | 
|  | self.visit_use_tree(use_tree) | 
|  | } | 
|  | )? | 
|  |  | 
|  | // `MutVisitor`-only methods | 
|  | $( | 
|  | // Span visiting is no longer used, but we keep it for now, | 
|  | // in case it's needed for something like #127241. | 
|  | #[inline] | 
|  | fn visit_span(&mut self, _sp: &$mut Span) { | 
|  | impl_visitable!(|&mut self: Span, visitor: &mut V, _extra: ()| { | 
|  | visitor.visit_span(self) | 
|  | }); | 
|  | // Do nothing. | 
|  | } | 
|  |  | 
|  | fn flat_map_foreign_item(&mut self, ni: Box<ForeignItem>) -> SmallVec<[Box<ForeignItem>; 1]> { | 
|  | walk_flat_map_foreign_item(self, ni) | 
|  | } | 
|  |  | 
|  | fn flat_map_item(&mut self, i: Box<Item>) -> SmallVec<[Box<Item>; 1]> { | 
|  | walk_flat_map_item(self, i) | 
|  | } | 
|  |  | 
|  | fn flat_map_field_def(&mut self, fd: FieldDef) -> SmallVec<[FieldDef; 1]> { | 
|  | walk_flat_map_field_def(self, fd) | 
|  | } | 
|  |  | 
|  | fn flat_map_assoc_item( | 
|  | &mut self, | 
|  | i: Box<AssocItem>, | 
|  | ctxt: AssocCtxt, | 
|  | ) -> SmallVec<[Box<AssocItem>; 1]> { | 
|  | walk_flat_map_assoc_item(self, i, ctxt) | 
|  | } | 
|  |  | 
|  | fn flat_map_stmt(&mut self, s: Stmt) -> SmallVec<[Stmt; 1]> { | 
|  | walk_flat_map_stmt(self, s) | 
|  | } | 
|  |  | 
|  | fn flat_map_arm(&mut self, arm: Arm) -> SmallVec<[Arm; 1]> { | 
|  | walk_flat_map_arm(self, arm) | 
|  | } | 
|  |  | 
|  | fn filter_map_expr(&mut self, e: Box<Expr>) -> Option<Box<Expr>> { | 
|  | walk_filter_map_expr(self, e) | 
|  | } | 
|  |  | 
|  | fn flat_map_variant(&mut self, v: Variant) -> SmallVec<[Variant; 1]> { | 
|  | walk_flat_map_variant(self, v) | 
|  | } | 
|  |  | 
|  | fn flat_map_param(&mut self, param: Param) -> SmallVec<[Param; 1]> { | 
|  | walk_flat_map_param(self, param) | 
|  | } | 
|  |  | 
|  | fn flat_map_generic_param(&mut self, param: GenericParam) -> SmallVec<[GenericParam; 1]> { | 
|  | walk_flat_map_generic_param(self, param) | 
|  | } | 
|  |  | 
|  | fn flat_map_expr_field(&mut self, f: ExprField) -> SmallVec<[ExprField; 1]> { | 
|  | walk_flat_map_expr_field(self, f) | 
|  | } | 
|  |  | 
|  | fn flat_map_where_predicate( | 
|  | &mut self, | 
|  | where_predicate: WherePredicate, | 
|  | ) -> SmallVec<[WherePredicate; 1]> { | 
|  | walk_flat_map_where_predicate(self, where_predicate) | 
|  | } | 
|  |  | 
|  | fn flat_map_pat_field(&mut self, fp: PatField) -> SmallVec<[PatField; 1]> { | 
|  | walk_flat_map_pat_field(self, fp) | 
|  | } | 
|  | )? | 
|  | } | 
|  |  | 
|  | pub trait WalkItemKind { | 
|  | type Ctxt; | 
|  | fn walk<$($lt,)? V: $Visitor$(<$lt>)?>( | 
|  | &$($lt)? $($mut)? self, | 
|  | span: Span, | 
|  | id: NodeId, | 
|  | visibility: &$($lt)? $($mut)? Visibility, | 
|  | ctxt: Self::Ctxt, | 
|  | vis: &mut V, | 
|  | ) -> V::Result; | 
|  | } | 
|  |  | 
|  | // this is only used by the MutVisitor. We include this symmetry here to make writing other functions easier | 
|  | $(${ignore($lt)} | 
|  | #[expect(unused, rustc::pass_by_value)] | 
|  | #[inline] | 
|  | )? | 
|  | fn visit_span<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, span: &$($lt)? $($mut)? Span) -> V::Result { | 
|  | $(${ignore($mut)} vis.visit_span(span))?; | 
|  | V::Result::output() | 
|  | } | 
|  |  | 
|  | $(impl_visitable!(|&$lt self: ThinVec<(UseTree, NodeId)>, vis: &mut V, _extra: ()| { | 
|  | for (nested_tree, nested_id) in self { | 
|  | try_visit!(vis.visit_nested_use_tree(nested_tree, *nested_id)); | 
|  | } | 
|  | V::Result::output() | 
|  | });)? | 
|  | $(impl_visitable_list!(<$mut> ThinVec<(UseTree, NodeId)>,);)? | 
|  |  | 
|  | fn walk_item_inner<$($lt,)? K: WalkItemKind, V: $Visitor$(<$lt>)?>( | 
|  | visitor: &mut V, | 
|  | item: &$($mut)? $($lt)? Item<K>, | 
|  | ctxt: K::Ctxt, | 
|  | ) -> V::Result { | 
|  | let Item { attrs, id, kind, vis, span, tokens: _ } = item; | 
|  | visit_visitable!($($mut)? visitor, id, attrs, vis); | 
|  | try_visit!(kind.walk(*span, *id, vis, ctxt, visitor)); | 
|  | visit_visitable!($($mut)? visitor, span); | 
|  | V::Result::output() | 
|  | } | 
|  |  | 
|  | // Do not implement `Walkable`/`MutWalkable` for *Item to avoid confusion. | 
|  | pub fn walk_item<$($lt,)? K: WalkItemKind<Ctxt = ()>, V: $Visitor$(<$lt>)?>( | 
|  | visitor: &mut V, | 
|  | item: &$($mut)? $($lt)? Item<K>, | 
|  | ) -> V::Result { | 
|  | walk_item_inner(visitor, item, ()) | 
|  | } | 
|  |  | 
|  | // Do not implement `Walkable`/`MutWalkable` for *Item to avoid confusion. | 
|  | pub fn walk_assoc_item<$($lt,)? K: WalkItemKind<Ctxt = AssocCtxt>, V: $Visitor$(<$lt>)?>( | 
|  | visitor: &mut V, | 
|  | item: &$($mut)? $($lt)? Item<K>, | 
|  | ctxt: AssocCtxt, | 
|  | ) -> V::Result { | 
|  | walk_item_inner(visitor, item, ctxt) | 
|  | } | 
|  |  | 
|  | impl WalkItemKind for ItemKind { | 
|  | type Ctxt = (); | 
|  | fn walk<$($lt,)? V: $Visitor$(<$lt>)?>( | 
|  | &$($lt)? $($mut)? self, | 
|  | span: Span, | 
|  | id: NodeId, | 
|  | visibility: &$($lt)? $($mut)? Visibility, | 
|  | _ctxt: Self::Ctxt, | 
|  | vis: &mut V, | 
|  | ) -> V::Result { | 
|  | match self { | 
|  | ItemKind::Fn(func) => { | 
|  | let kind = FnKind::Fn(FnCtxt::Free, visibility, &$($mut)? *func); | 
|  | try_visit!(vis.visit_fn(kind, span, id)); | 
|  | } | 
|  | ItemKind::ExternCrate(orig_name, ident) => | 
|  | visit_visitable!($($mut)? vis, orig_name, ident), | 
|  | ItemKind::Use(use_tree) => | 
|  | visit_visitable!($($mut)? vis, use_tree), | 
|  | ItemKind::Static(item) => | 
|  | visit_visitable!($($mut)? vis, item), | 
|  | ItemKind::Const(item) => | 
|  | visit_visitable!($($mut)? vis, item), | 
|  | ItemKind::Mod(safety, ident, mod_kind) => | 
|  | visit_visitable!($($mut)? vis, safety, ident, mod_kind), | 
|  | ItemKind::ForeignMod(nm) => | 
|  | visit_visitable!($($mut)? vis, nm), | 
|  | ItemKind::GlobalAsm(asm) => | 
|  | visit_visitable!($($mut)? vis, asm), | 
|  | ItemKind::TyAlias(ty_alias) => | 
|  | visit_visitable!($($mut)? vis, ty_alias), | 
|  | ItemKind::Enum(ident, generics, enum_definition) => | 
|  | visit_visitable!($($mut)? vis, ident, generics, enum_definition), | 
|  | ItemKind::Struct(ident, generics, variant_data) | 
|  | | ItemKind::Union(ident, generics, variant_data) => | 
|  | visit_visitable!($($mut)? vis, ident, generics, variant_data), | 
|  | ItemKind::Impl(impl_) => | 
|  | visit_visitable!($($mut)? vis, impl_), | 
|  | ItemKind::Trait(trait_) => | 
|  | visit_visitable!($($mut)? vis, trait_), | 
|  | ItemKind::TraitAlias(box TraitAlias { constness, ident, generics, bounds}) => { | 
|  | visit_visitable!($($mut)? vis, constness, ident, generics); | 
|  | visit_visitable_with!($($mut)? vis, bounds, BoundKind::Bound) | 
|  | } | 
|  | ItemKind::MacCall(m) => | 
|  | visit_visitable!($($mut)? vis, m), | 
|  | ItemKind::MacroDef(ident, def) => | 
|  | visit_visitable!($($mut)? vis, ident, def), | 
|  | ItemKind::Delegation(delegation) => | 
|  | visit_visitable!($($mut)? vis, delegation), | 
|  | ItemKind::DelegationMac(dm) => | 
|  | visit_visitable!($($mut)? vis, dm), | 
|  | } | 
|  | V::Result::output() | 
|  | } | 
|  | } | 
|  |  | 
|  | impl WalkItemKind for AssocItemKind { | 
|  | type Ctxt = AssocCtxt; | 
|  | fn walk<$($lt,)? V: $Visitor$(<$lt>)?>( | 
|  | &$($lt)? $($mut)? self, | 
|  | span: Span, | 
|  | id: NodeId, | 
|  | visibility: &$($lt)? $($mut)? Visibility, | 
|  | ctxt: Self::Ctxt, | 
|  | vis: &mut V, | 
|  | ) -> V::Result { | 
|  | match self { | 
|  | AssocItemKind::Const(item) => | 
|  | visit_visitable!($($mut)? vis, item), | 
|  | AssocItemKind::Fn(func) => { | 
|  | let kind = FnKind::Fn(FnCtxt::Assoc(ctxt), visibility, &$($mut)? *func); | 
|  | try_visit!(vis.visit_fn(kind, span, id)) | 
|  | } | 
|  | AssocItemKind::Type(alias) => | 
|  | visit_visitable!($($mut)? vis, alias), | 
|  | AssocItemKind::MacCall(mac) => | 
|  | visit_visitable!($($mut)? vis, mac), | 
|  | AssocItemKind::Delegation(delegation) => | 
|  | visit_visitable!($($mut)? vis, delegation), | 
|  | AssocItemKind::DelegationMac(dm) => | 
|  | visit_visitable!($($mut)? vis, dm), | 
|  | } | 
|  | V::Result::output() | 
|  | } | 
|  | } | 
|  |  | 
|  | impl WalkItemKind for ForeignItemKind { | 
|  | type Ctxt = (); | 
|  | fn walk<$($lt,)? V: $Visitor$(<$lt>)?>( | 
|  | &$($lt)? $($mut)? self, | 
|  | span: Span, | 
|  | id: NodeId, | 
|  | visibility: &$($lt)? $($mut)? Visibility, | 
|  | _ctxt: Self::Ctxt, | 
|  | vis: &mut V, | 
|  | ) -> V::Result { | 
|  | match self { | 
|  | ForeignItemKind::Static(item) => | 
|  | visit_visitable!($($mut)? vis, item), | 
|  | ForeignItemKind::Fn(func) => { | 
|  | let kind = FnKind::Fn(FnCtxt::Foreign, visibility, &$($mut)?*func); | 
|  | try_visit!(vis.visit_fn(kind, span, id)) | 
|  | } | 
|  | ForeignItemKind::TyAlias(alias) => | 
|  | visit_visitable!($($mut)? vis, alias), | 
|  | ForeignItemKind::MacCall(mac) => | 
|  | visit_visitable!($($mut)? vis, mac), | 
|  | } | 
|  | V::Result::output() | 
|  | } | 
|  | } | 
|  |  | 
|  | pub fn walk_fn<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, kind: FnKind<$($lt)? $(${ignore($mut)} '_)?>) -> V::Result { | 
|  | match kind { | 
|  | FnKind::Fn( | 
|  | _ctxt, | 
|  | // Visibility is visited as a part of the item. | 
|  | _vis, | 
|  | Fn { defaultness, ident, sig, generics, contract, body, define_opaque }, | 
|  | ) => { | 
|  | let FnSig { header, decl, span } = sig; | 
|  | visit_visitable!($($mut)? vis, | 
|  | defaultness, ident, header, generics, decl, | 
|  | contract, body, span, define_opaque | 
|  | ) | 
|  | } | 
|  | FnKind::Closure(binder, coroutine_kind, decl, body) => | 
|  | visit_visitable!($($mut)? vis, binder, coroutine_kind, decl, body), | 
|  | } | 
|  | V::Result::output() | 
|  | } | 
|  |  | 
|  | impl_walkable!(|&$($mut)? $($lt)? self: Impl, vis: &mut V| { | 
|  | let Impl { generics, of_trait, self_ty, items } = self; | 
|  | try_visit!(vis.visit_generics(generics)); | 
|  | if let Some(box of_trait) = of_trait { | 
|  | let TraitImplHeader { defaultness, safety, constness, polarity, trait_ref } = of_trait; | 
|  | visit_visitable!($($mut)? vis, defaultness, safety, constness, polarity, trait_ref); | 
|  | } | 
|  | try_visit!(vis.visit_ty(self_ty)); | 
|  | visit_visitable_with!($($mut)? vis, items, AssocCtxt::Impl { of_trait: of_trait.is_some() }); | 
|  | V::Result::output() | 
|  | }); | 
|  |  | 
|  | // Special case to call `visit_method_receiver_expr`. | 
|  | impl_walkable!(|&$($mut)? $($lt)? self: MethodCall, vis: &mut V| { | 
|  | let MethodCall { seg, receiver, args, span } = self; | 
|  | try_visit!(vis.visit_method_receiver_expr(receiver)); | 
|  | visit_visitable!($($mut)? vis, seg, args, span); | 
|  | V::Result::output() | 
|  | }); | 
|  |  | 
|  | impl_walkable!(|&$($mut)? $($lt)? self: Expr, vis: &mut V| { | 
|  | let Expr { id, kind, span, attrs, tokens: _ } = self; | 
|  | visit_visitable!($($mut)? vis, id, attrs); | 
|  | match kind { | 
|  | ExprKind::Array(exprs) => | 
|  | visit_visitable!($($mut)? vis, exprs), | 
|  | ExprKind::ConstBlock(anon_const) => | 
|  | visit_visitable!($($mut)? vis, anon_const), | 
|  | ExprKind::Repeat(element, count) => | 
|  | visit_visitable!($($mut)? vis, element, count), | 
|  | ExprKind::Struct(se) => | 
|  | visit_visitable!($($mut)? vis, se), | 
|  | ExprKind::Tup(exprs) => | 
|  | visit_visitable!($($mut)? vis, exprs), | 
|  | ExprKind::Call(callee_expression, arguments) => | 
|  | visit_visitable!($($mut)? vis, callee_expression, arguments), | 
|  | ExprKind::MethodCall(mc) => | 
|  | visit_visitable!($($mut)? vis, mc), | 
|  | ExprKind::Binary(op, lhs, rhs) => | 
|  | visit_visitable!($($mut)? vis, op, lhs, rhs), | 
|  | ExprKind::AddrOf(kind, mutbl, subexpression) => | 
|  | visit_visitable!($($mut)? vis, kind, mutbl, subexpression), | 
|  | ExprKind::Unary(op, subexpression) => | 
|  | visit_visitable!($($mut)? vis, op, subexpression), | 
|  | ExprKind::Cast(subexpression, typ) | ExprKind::Type(subexpression, typ) => | 
|  | visit_visitable!($($mut)? vis, subexpression, typ), | 
|  | ExprKind::Let(pat, expr, span, _recovered) => | 
|  | visit_visitable!($($mut)? vis, pat, expr, span), | 
|  | ExprKind::If(head_expression, if_block, optional_else) => | 
|  | visit_visitable!($($mut)? vis, head_expression, if_block, optional_else), | 
|  | ExprKind::While(subexpression, block, opt_label) => | 
|  | visit_visitable!($($mut)? vis, subexpression, block, opt_label), | 
|  | ExprKind::ForLoop { pat, iter, body, label, kind } => | 
|  | visit_visitable!($($mut)? vis, pat, iter, body, label, kind), | 
|  | ExprKind::Loop(block, opt_label, span) => | 
|  | visit_visitable!($($mut)? vis, block, opt_label, span), | 
|  | ExprKind::Match(subexpression, arms, kind) => | 
|  | visit_visitable!($($mut)? vis, subexpression, arms, kind), | 
|  | ExprKind::Closure(box Closure { | 
|  | binder, | 
|  | capture_clause, | 
|  | coroutine_kind, | 
|  | constness, | 
|  | movability, | 
|  | fn_decl, | 
|  | body, | 
|  | fn_decl_span, | 
|  | fn_arg_span, | 
|  | }) => { | 
|  | visit_visitable!($($mut)? vis, constness, movability, capture_clause); | 
|  | let kind = FnKind::Closure(binder, coroutine_kind, fn_decl, body); | 
|  | try_visit!(vis.visit_fn(kind, *span, *id)); | 
|  | visit_visitable!($($mut)? vis, fn_decl_span, fn_arg_span); | 
|  | } | 
|  | ExprKind::Block(block, opt_label) => | 
|  | visit_visitable!($($mut)? vis, block, opt_label), | 
|  | ExprKind::Gen(capt, body, kind, decl_span) => | 
|  | visit_visitable!($($mut)? vis, capt, body, kind, decl_span), | 
|  | ExprKind::Await(expr, span) | ExprKind::Use(expr, span) => | 
|  | visit_visitable!($($mut)? vis, expr, span), | 
|  | ExprKind::Assign(lhs, rhs, span) => | 
|  | visit_visitable!($($mut)? vis, lhs, rhs, span), | 
|  | ExprKind::AssignOp(op, lhs, rhs) => | 
|  | visit_visitable!($($mut)? vis, op, lhs, rhs), | 
|  | ExprKind::Field(subexpression, ident) => | 
|  | visit_visitable!($($mut)? vis, subexpression, ident), | 
|  | ExprKind::Index(main_expression, index_expression, span) => | 
|  | visit_visitable!($($mut)? vis, main_expression, index_expression, span), | 
|  | ExprKind::Range(start, end, limit) => | 
|  | visit_visitable!($($mut)? vis, start, end, limit), | 
|  | ExprKind::Underscore => {} | 
|  | ExprKind::Path(maybe_qself, path) => | 
|  | visit_visitable!($($mut)? vis, maybe_qself, path), | 
|  | ExprKind::Break(opt_label, opt_expr) => | 
|  | visit_visitable!($($mut)? vis, opt_label, opt_expr), | 
|  | ExprKind::Continue(opt_label) => | 
|  | visit_visitable!($($mut)? vis, opt_label), | 
|  | ExprKind::Ret(optional_expression) | ExprKind::Yeet(optional_expression) => | 
|  | visit_visitable!($($mut)? vis, optional_expression), | 
|  | ExprKind::Become(expr) => | 
|  | visit_visitable!($($mut)? vis, expr), | 
|  | ExprKind::MacCall(mac) => | 
|  | visit_visitable!($($mut)? vis, mac), | 
|  | ExprKind::Paren(subexpression) => | 
|  | visit_visitable!($($mut)? vis, subexpression), | 
|  | ExprKind::InlineAsm(asm) => | 
|  | visit_visitable!($($mut)? vis, asm), | 
|  | ExprKind::FormatArgs(f) => | 
|  | visit_visitable!($($mut)? vis, f), | 
|  | ExprKind::OffsetOf(container, fields) => | 
|  | visit_visitable!($($mut)? vis, container, fields), | 
|  | ExprKind::Yield(kind) => | 
|  | visit_visitable!($($mut)? vis, kind), | 
|  | ExprKind::Try(subexpression) => | 
|  | visit_visitable!($($mut)? vis, subexpression), | 
|  | ExprKind::TryBlock(body) => | 
|  | visit_visitable!($($mut)? vis, body), | 
|  | ExprKind::Lit(token) => | 
|  | visit_visitable!($($mut)? vis, token), | 
|  | ExprKind::IncludedBytes(bytes) => | 
|  | visit_visitable!($($mut)? vis, bytes), | 
|  | ExprKind::UnsafeBinderCast(kind, expr, ty) => | 
|  | visit_visitable!($($mut)? vis, kind, expr, ty), | 
|  | ExprKind::Err(_guar) => {} | 
|  | ExprKind::Dummy => {} | 
|  | } | 
|  |  | 
|  | visit_span(vis, span) | 
|  | }); | 
|  |  | 
|  | define_named_walk!($(($mut))? $Visitor$(<$lt>)? | 
|  | pub fn walk_anon_const(AnonConst); | 
|  | pub fn walk_arm(Arm); | 
|  | //pub fn walk_assoc_item(AssocItem, _ctxt: AssocCtxt); | 
|  | pub fn walk_assoc_item_constraint(AssocItemConstraint); | 
|  | pub fn walk_attribute(Attribute); | 
|  | pub fn walk_block(Block); | 
|  | //pub fn walk_nested_use_tree((UseTree, NodeId)); | 
|  | pub fn walk_capture_by(CaptureBy); | 
|  | pub fn walk_closure_binder(ClosureBinder); | 
|  | pub fn walk_contract(FnContract); | 
|  | pub fn walk_coroutine_kind(CoroutineKind); | 
|  | pub fn walk_crate(Crate); | 
|  | pub fn walk_expr(Expr); | 
|  | pub fn walk_expr_field(ExprField); | 
|  | pub fn walk_field_def(FieldDef); | 
|  | pub fn walk_fn_decl(FnDecl); | 
|  | pub fn walk_fn_header(FnHeader); | 
|  | pub fn walk_fn_ret_ty(FnRetTy); | 
|  | //pub fn walk_foreign_item(ForeignItem); | 
|  | pub fn walk_foreign_mod(ForeignMod); | 
|  | pub fn walk_format_args(FormatArgs); | 
|  | pub fn walk_generic_arg(GenericArg); | 
|  | pub fn walk_generic_args(GenericArgs); | 
|  | pub fn walk_generic_param(GenericParam); | 
|  | pub fn walk_generics(Generics); | 
|  | pub fn walk_inline_asm(InlineAsm); | 
|  | pub fn walk_inline_asm_sym(InlineAsmSym); | 
|  | //pub fn walk_item(Item); | 
|  | pub fn walk_label(Label); | 
|  | pub fn walk_lifetime(Lifetime); | 
|  | pub fn walk_local(Local); | 
|  | pub fn walk_mac(MacCall); | 
|  | pub fn walk_macro_def(MacroDef); | 
|  | pub fn walk_param_bound(GenericBound); | 
|  | pub fn walk_param(Param); | 
|  | pub fn walk_pat_field(PatField); | 
|  | pub fn walk_path(Path); | 
|  | pub fn walk_path_segment(PathSegment); | 
|  | pub fn walk_pat(Pat); | 
|  | pub fn walk_poly_trait_ref(PolyTraitRef); | 
|  | pub fn walk_precise_capturing_arg(PreciseCapturingArg); | 
|  | pub fn walk_qself(QSelf); | 
|  | pub fn walk_trait_ref(TraitRef); | 
|  | pub fn walk_ty_pat(TyPat); | 
|  | pub fn walk_ty(Ty); | 
|  | pub fn walk_use_tree(UseTree); | 
|  | pub fn walk_variant_data(VariantData); | 
|  | pub fn walk_variant(Variant); | 
|  | pub fn walk_vis(Visibility); | 
|  | pub fn walk_where_predicate_kind(WherePredicateKind); | 
|  | pub fn walk_where_predicate(WherePredicate); | 
|  | ); | 
|  | }; | 
|  | } | 
|  |  | 
|  | common_visitor_and_walkers!(Visitor<'a>); | 
|  |  | 
|  | macro_rules! generate_list_visit_fns { | 
|  | ($($name:ident, $Ty:ty, $visit_fn:ident$(, $param:ident: $ParamTy:ty)*;)+) => { | 
|  | $( | 
|  | #[allow(unused_parens)] | 
|  | impl<'a, V: Visitor<'a>> Visitable<'a, V> for ThinVec<$Ty> { | 
|  | type Extra = ($($ParamTy),*); | 
|  |  | 
|  | #[inline] | 
|  | fn visit( | 
|  | &'a self, | 
|  | visitor: &mut V, | 
|  | ($($param),*): Self::Extra, | 
|  | ) -> V::Result { | 
|  | $name(visitor, self $(, $param)*) | 
|  | } | 
|  | } | 
|  |  | 
|  | fn $name<'a, V: Visitor<'a>>( | 
|  | vis: &mut V, | 
|  | values: &'a ThinVec<$Ty>, | 
|  | $( | 
|  | $param: $ParamTy, | 
|  | )* | 
|  | ) -> V::Result { | 
|  | walk_list!(vis, $visit_fn, values$(,$param)*); | 
|  | V::Result::output() | 
|  | } | 
|  | )+ | 
|  | } | 
|  | } | 
|  |  | 
|  | generate_list_visit_fns! { | 
|  | visit_items, Box<Item>, visit_item; | 
|  | visit_foreign_items, Box<ForeignItem>, visit_foreign_item; | 
|  | visit_generic_params, GenericParam, visit_generic_param; | 
|  | visit_stmts, Stmt, visit_stmt; | 
|  | visit_exprs, Box<Expr>, visit_expr; | 
|  | visit_expr_fields, ExprField, visit_expr_field; | 
|  | visit_pat_fields, PatField, visit_pat_field; | 
|  | visit_variants, Variant, visit_variant; | 
|  | visit_assoc_items, Box<AssocItem>, visit_assoc_item, ctxt: AssocCtxt; | 
|  | visit_where_predicates, WherePredicate, visit_where_predicate; | 
|  | visit_params, Param, visit_param; | 
|  | visit_field_defs, FieldDef, visit_field_def; | 
|  | visit_arms, Arm, visit_arm; | 
|  | } | 
|  |  | 
|  | pub fn walk_stmt<'a, V: Visitor<'a>>(visitor: &mut V, statement: &'a Stmt) -> V::Result { | 
|  | let Stmt { id, kind, span: _ } = statement; | 
|  | try_visit!(visitor.visit_id(*id)); | 
|  | match kind { | 
|  | StmtKind::Let(local) => try_visit!(visitor.visit_local(local)), | 
|  | StmtKind::Item(item) => try_visit!(visitor.visit_item(item)), | 
|  | StmtKind::Expr(expr) | StmtKind::Semi(expr) => try_visit!(visitor.visit_expr(expr)), | 
|  | StmtKind::Empty => {} | 
|  | StmtKind::MacCall(mac) => { | 
|  | let MacCallStmt { mac, attrs, style: _, tokens: _ } = &**mac; | 
|  | walk_list!(visitor, visit_attribute, attrs); | 
|  | try_visit!(visitor.visit_mac_call(mac)); | 
|  | } | 
|  | } | 
|  | V::Result::output() | 
|  | } |