From cf06285aab63bc30324c7fad1c759e5147c04cf1 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 2 Sep 2026 18:29:14 +1000 Subject: [PATCH 1/9] Remove `impl Visitable for (T,)` It's unused, and we should never have a single-element tuple in the AST. --- compiler/rustc_ast/src/mut_visit.rs | 10 ---------- compiler/rustc_ast/src/visit.rs | 10 ---------- 2 files changed, 20 deletions(-) diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 0b81ad5ff952e..68caaa4b01c21 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -97,16 +97,6 @@ where } } -impl MutVisitable for (T,) -where - T: MutVisitable, -{ - type Extra = T::Extra; - fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra) { - self.0.visit_mut(visitor, extra); - } -} - impl MutVisitable for (T1, T2) where T1: MutVisitable, diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 68cf07c61682f..b39bce793a558 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -141,16 +141,6 @@ where } } -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 = ()>, From aab7df718f6f9b440cdd20578d878ac017e90787 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 2 Sep 2026 16:48:14 +1000 Subject: [PATCH 2/9] Inline and remove `walk_walkable!` macros They are trivial and the code is clearer with them gone. --- compiler/rustc_ast/src/mut_visit.rs | 10 ++-------- compiler/rustc_ast/src/visit.rs | 10 ++-------- 2 files changed, 4 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 68caaa4b01c21..62af557904430 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -155,12 +155,6 @@ macro_rules! visit_visitable_with { }; } -macro_rules! walk_walkable { - ($visitor:expr, $expr:expr, mut) => { - MutWalkable::walk_mut($expr, $visitor) - }; -} - macro_rules! impl_visitable { (|&mut $self:ident: $self_ty:ty, $vis:ident: &mut $vis_ty:ident, @@ -233,7 +227,7 @@ macro_rules! impl_visitable_calling_walkable { let ($($extra_name)?) = extra; visitor.$method(self $(, $extra_name)?); }); - walk_walkable!(self, node, mut) + MutWalkable::walk_mut(node, self) })* } } @@ -243,7 +237,7 @@ macro_rules! define_named_walk { $( pub fn $method:ident($ty:ty); )* ) => { $(pub fn $method(visitor: &mut V, node: &mut $ty) { - walk_walkable!(visitor, node, mut) + MutWalkable::walk_mut(node, visitor) })* }; } diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index b39bce793a558..672ec90d08519 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -203,12 +203,6 @@ macro_rules! visit_visitable_with { }; } -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, @@ -284,7 +278,7 @@ macro_rules! impl_visitable_calling_walkable { let ($($extra_name)?) = extra; visitor.$method(self $(, $extra_name)?) }); - walk_walkable!(self, node, ) + Walkable::walk_ref(node, self) })* }; } @@ -294,7 +288,7 @@ macro_rules! define_named_walk { $( 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,) + Walkable::walk_ref(node, visitor) })* }; } From 1626def82e22a1a66ef32ce682bba1fbcf692c52 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 2 Sep 2026 18:24:05 +1000 Subject: [PATCH 3/9] Inline and remove `MutVisitor`-only `visit_span` It has only two call sites and the code is clearer with it gone. --- compiler/rustc_ast/src/visit.rs | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 672ec90d08519..362fc872bed1c 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -540,7 +540,8 @@ macro_rules! common_visitor_and_walkers { impl_visitable!(|&$($lt)? $($mut)? self: Ident, visitor: &mut V, _extra: ()| { visitor.visit_ident(self) }); - visit_span(self, span) + visit_visitable!($($mut)? self, span); + Self::Result::output() } // This macro defines a custom visit method for each listed type. @@ -759,17 +760,6 @@ macro_rules! common_visitor_and_walkers { ) -> 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::disallowed_pass_by_ref)] - #[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)); @@ -1078,7 +1068,8 @@ macro_rules! common_visitor_and_walkers { ExprKind::Dummy => {} } - visit_span(vis, span) + visit_visitable!($($mut)? vis, span); + V::Result::output() }); define_named_walk!($(($mut))? $Visitor$(<$lt>)? From 1177ad0ae2d2f1a0b56ce740bf7306e7bf0938e5 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 2 Sep 2026 21:43:22 +1000 Subject: [PATCH 4/9] Remove optional and unused `(K, Kb)` arg from `impl_walkable!` macros --- compiler/rustc_ast/src/mut_visit.rs | 4 ++-- compiler/rustc_ast/src/visit.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 62af557904430..38e458471ac53 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -170,10 +170,10 @@ macro_rules! impl_visitable { } macro_rules! impl_walkable { - ($(<$K:ident: $Kb:ident>)? |&mut $self:ident: $self_ty:ty, + (|&mut $self:ident: $self_ty:ty, $vis:ident: &mut $vis_ty:ident| $block:block) => { #[allow(unused_parens, non_local_definitions)] - impl<$($K: $Kb,)? $vis_ty: MutVisitor> MutWalkable<$vis_ty> for $self_ty { + impl<$vis_ty: MutVisitor> MutWalkable<$vis_ty> for $self_ty { fn walk_mut(&mut $self, $vis: &mut $vis_ty) -> V::Result { $block } diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 362fc872bed1c..b82d77e99f6f4 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -218,10 +218,10 @@ macro_rules! impl_visitable { } macro_rules! impl_walkable { - ($(<$K:ident: $Kb:ident>)? |&$lt:lifetime $self:ident: $self_ty:ty, + (|&$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 { + impl<$lt, $vis_ty: Visitor<$lt>> Walkable<$lt, $vis_ty> for $self_ty { fn walk_ref(&$lt $self, $vis: &mut $vis_ty) -> V::Result { $block } From 5503fdadc44e352b7b1eb30e3c8b334ca321e1f4 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 2 Sep 2026 22:12:37 +1000 Subject: [PATCH 5/9] Remove unnecessary `allow`s from `impl_walkable!` macro --- compiler/rustc_ast/src/mut_visit.rs | 1 - compiler/rustc_ast/src/visit.rs | 1 - 2 files changed, 2 deletions(-) diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 38e458471ac53..00afe203d8ad5 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -172,7 +172,6 @@ macro_rules! impl_visitable { macro_rules! impl_walkable { (|&mut $self:ident: $self_ty:ty, $vis:ident: &mut $vis_ty:ident| $block:block) => { - #[allow(unused_parens, non_local_definitions)] impl<$vis_ty: MutVisitor> MutWalkable<$vis_ty> for $self_ty { fn walk_mut(&mut $self, $vis: &mut $vis_ty) -> V::Result { $block diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index b82d77e99f6f4..50d40d3da544e 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -220,7 +220,6 @@ macro_rules! impl_visitable { macro_rules! impl_walkable { (|&$lt:lifetime $self:ident: $self_ty:ty, $vis:ident: &mut $vis_ty:ident| $block:block) => { - #[allow(unused_parens, non_local_definitions)] impl<$lt, $vis_ty: Visitor<$lt>> Walkable<$lt, $vis_ty> for $self_ty { fn walk_ref(&$lt $self, $vis: &mut $vis_ty) -> V::Result { $block From 1d894d764554f14fffc7242a94b36ca0ea843a9f Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 2 Sep 2026 16:42:14 +1000 Subject: [PATCH 6/9] Remove many `$($mut)?` occurrences This is a very common pattern in the AST visitor code: ``` visit_visitable!($($mut)? visitor, a, b, c); ``` It looks like the `$($mut)?` selects between the immutable visitor's `visit_visitable!` (which doesn't accept `mut` at the start) and the mutable visitor's (which does accept `mut` at the start). That would make sense if `visit_visitable!` was a single macro with separate rules for the immutable and mutable cases. But that's not the case. The two `visit_visitable!` definitions are in different modules and at any call site only one of them is visible within the relevant `common_visitor_and_walkers!` invocation. So the `$($mut)?` can be removed from the many `visit_visitable!` calls, and also the `visit_visitable_with!` and `define_named_walk!` calls. This makes the code easier to read. --- compiler/rustc_ast/src/mut_visit.rs | 6 +- compiler/rustc_ast/src/visit.rs | 166 ++++++++++++++-------------- 2 files changed, 86 insertions(+), 86 deletions(-) diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 00afe203d8ad5..e7bf694e4ea5d 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -144,13 +144,13 @@ pub trait MutWalkable { } macro_rules! visit_visitable { - (mut $visitor:expr, $($expr:expr),* $(,)?) => {{ + ($visitor:expr, $($expr:expr),* $(,)?) => {{ $(MutVisitable::visit_mut($expr, $visitor, ());)* }}; } macro_rules! visit_visitable_with { - (mut $visitor:expr, $expr:expr, $extra:expr $(,)?) => { + ($visitor:expr, $expr:expr, $extra:expr $(,)?) => { MutVisitable::visit_mut($expr, $visitor, $extra) }; } @@ -232,7 +232,7 @@ macro_rules! impl_visitable_calling_walkable { } macro_rules! define_named_walk { - ((mut) $Visitor:ident + ($Visitor:ident $( pub fn $method:ident($ty:ty); )* ) => { $(pub fn $method(visitor: &mut V, node: &mut $ty) { diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 50d40d3da544e..d160c2e87badb 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -539,7 +539,7 @@ macro_rules! common_visitor_and_walkers { impl_visitable!(|&$($lt)? $($mut)? self: Ident, visitor: &mut V, _extra: ()| { visitor.visit_ident(self) }); - visit_visitable!($($mut)? self, span); + visit_visitable!(self, span); Self::Result::output() } @@ -773,9 +773,9 @@ macro_rules! common_visitor_and_walkers { ctxt: K::Ctxt, ) -> V::Result { let Item { attrs, id, kind, vis, span, tokens: _ } = item; - visit_visitable!($($mut)? visitor, id, attrs, vis); + visit_visitable!(visitor, id, attrs, vis); try_visit!(kind.walk(attrs, *span, *id, vis, ctxt, visitor)); - visit_visitable!($($mut)? visitor, span); + visit_visitable!(visitor, span); V::Result::output() } @@ -813,46 +813,46 @@ macro_rules! common_visitor_and_walkers { try_visit!(vis.visit_fn(kind, attrs, span, id)); } ItemKind::ExternCrate(orig_name, ident) => - visit_visitable!($($mut)? vis, orig_name, ident), + visit_visitable!(vis, orig_name, ident), ItemKind::Use(use_tree) => - visit_visitable!($($mut)? vis, use_tree), + visit_visitable!(vis, use_tree), ItemKind::Static(item) => - visit_visitable!($($mut)? vis, item), + visit_visitable!(vis, item), ItemKind::ConstBlock(item) => - visit_visitable!($($mut)? vis, item), + visit_visitable!(vis, item), ItemKind::Const(item) => - visit_visitable!($($mut)? vis, item), + visit_visitable!(vis, item), ItemKind::Mod(safety, ident, mod_kind) => - visit_visitable!($($mut)? vis, safety, ident, mod_kind), + visit_visitable!(vis, safety, ident, mod_kind), ItemKind::ForeignMod(nm) => - visit_visitable!($($mut)? vis, nm), + visit_visitable!(vis, nm), ItemKind::GlobalAsm(asm) => - visit_visitable!($($mut)? vis, asm), + visit_visitable!(vis, asm), ItemKind::TyAlias(ty_alias) => - visit_visitable!($($mut)? vis, ty_alias), + visit_visitable!(vis, ty_alias), ItemKind::Enum(ident, generics, enum_definition) => - visit_visitable!($($mut)? vis, ident, generics, enum_definition), + visit_visitable!(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), + visit_visitable!(vis, ident, generics, variant_data), ItemKind::Impl(impl_) => - visit_visitable!($($mut)? vis, impl_), + visit_visitable!(vis, impl_), ItemKind::Trait(trait_) => - visit_visitable!($($mut)? vis, trait_), + visit_visitable!(vis, trait_), ItemKind::TraitAlias(TraitAlias { constness, ident, generics, bounds}) => { - visit_visitable!($($mut)? vis, constness, ident, generics); - visit_visitable_with!($($mut)? vis, bounds, BoundKind::Bound) + visit_visitable!(vis, constness, ident, generics); + visit_visitable_with!(vis, bounds, BoundKind::Bound) } ItemKind::MacCall(m) => - visit_visitable!($($mut)? vis, m), + visit_visitable!(vis, m), ItemKind::MacroDef(ident, def) => - visit_visitable!($($mut)? vis, ident, def), + visit_visitable!(vis, ident, def), ItemKind::Delegation(delegation) => - visit_visitable!($($mut)? vis, delegation), + visit_visitable!(vis, delegation), ItemKind::DelegationMac(dm) => - visit_visitable!($($mut)? vis, dm), + visit_visitable!(vis, dm), ItemKind::TestBinderConstraints(item) => - visit_visitable!($($mut)? vis, item), + visit_visitable!(vis, item), } V::Result::output() } @@ -871,19 +871,19 @@ macro_rules! common_visitor_and_walkers { ) -> V::Result { match self { AssocItemKind::Const(item) => - visit_visitable!($($mut)? vis, item), + visit_visitable!(vis, item), AssocItemKind::Fn(func) => { let kind = FnKind::Fn(FnCtxt::Assoc(ctxt), visibility, &$($mut)? *func); try_visit!(vis.visit_fn(kind, attrs, span, id)) } AssocItemKind::Type(alias) => - visit_visitable!($($mut)? vis, alias), + visit_visitable!(vis, alias), AssocItemKind::MacCall(mac) => - visit_visitable!($($mut)? vis, mac), + visit_visitable!(vis, mac), AssocItemKind::Delegation(delegation) => - visit_visitable!($($mut)? vis, delegation), + visit_visitable!(vis, delegation), AssocItemKind::DelegationMac(dm) => - visit_visitable!($($mut)? vis, dm), + visit_visitable!(vis, dm), } V::Result::output() } @@ -902,15 +902,15 @@ macro_rules! common_visitor_and_walkers { ) -> V::Result { match self { ForeignItemKind::Static(item) => - visit_visitable!($($mut)? vis, item), + visit_visitable!(vis, item), ForeignItemKind::Fn(func) => { let kind = FnKind::Fn(FnCtxt::Foreign, visibility, &$($mut)?*func); try_visit!(vis.visit_fn(kind, attrs, span, id)) } ForeignItemKind::TyAlias(alias) => - visit_visitable!($($mut)? vis, alias), + visit_visitable!(vis, alias), ForeignItemKind::MacCall(mac) => - visit_visitable!($($mut)? vis, mac), + visit_visitable!(vis, mac), } V::Result::output() } @@ -925,13 +925,13 @@ macro_rules! common_visitor_and_walkers { Fn { defaultness, ident, sig, generics, contract, body, define_opaque, eii_impl }, ) => { let FnSig { header, decl, span } = sig; - visit_visitable!($($mut)? vis, + visit_visitable!(vis, defaultness, ident, header, generics, decl, contract, body, span, define_opaque, eii_impl ); } FnKind::Closure(binder, coroutine_marker, decl, body) => - visit_visitable!($($mut)? vis, binder, coroutine_marker, decl, body), + visit_visitable!(vis, binder, coroutine_marker, decl, body), } V::Result::output() } @@ -941,10 +941,10 @@ macro_rules! common_visitor_and_walkers { try_visit!(vis.visit_generics(generics)); if let Some(of_trait) = of_trait { let TraitImplHeader { defaultness, safety, polarity, trait_ref } = of_trait; - visit_visitable!($($mut)? vis, defaultness, safety, polarity, trait_ref); + visit_visitable!(vis, defaultness, safety, polarity, trait_ref); } try_visit!(vis.visit_ty(self_ty)); - visit_visitable_with!($($mut)? vis, items, AssocCtxt::Impl { of_trait: of_trait.is_some() }); + visit_visitable_with!(vis, items, AssocCtxt::Impl { of_trait: of_trait.is_some() }); V::Result::output() }); @@ -952,48 +952,48 @@ macro_rules! common_visitor_and_walkers { 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); + visit_visitable!(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); + visit_visitable!(vis, id, attrs); match kind { ExprKind::Array(exprs) => - visit_visitable!($($mut)? vis, exprs), + visit_visitable!(vis, exprs), ExprKind::ConstBlock(anon_const) => - visit_visitable!($($mut)? vis, anon_const), + visit_visitable!(vis, anon_const), ExprKind::Repeat(element, count) => - visit_visitable!($($mut)? vis, element, count), + visit_visitable!(vis, element, count), ExprKind::Struct(se) => - visit_visitable!($($mut)? vis, se), + visit_visitable!(vis, se), ExprKind::Tup(exprs) => - visit_visitable!($($mut)? vis, exprs), + visit_visitable!(vis, exprs), ExprKind::Call(callee_expression, arguments) => - visit_visitable!($($mut)? vis, callee_expression, arguments), + visit_visitable!(vis, callee_expression, arguments), ExprKind::MethodCall(mc) => - visit_visitable!($($mut)? vis, mc), + visit_visitable!(vis, mc), ExprKind::Binary(op, lhs, rhs) => - visit_visitable!($($mut)? vis, op, lhs, rhs), + visit_visitable!(vis, op, lhs, rhs), ExprKind::AddrOf(kind, mutbl, subexpression) => - visit_visitable!($($mut)? vis, kind, mutbl, subexpression), + visit_visitable!(vis, kind, mutbl, subexpression), ExprKind::Unary(op, subexpression) => - visit_visitable!($($mut)? vis, op, subexpression), + visit_visitable!(vis, op, subexpression), ExprKind::Cast(subexpression, typ) | ExprKind::Type(subexpression, typ) => - visit_visitable!($($mut)? vis, subexpression, typ), + visit_visitable!(vis, subexpression, typ), ExprKind::Let(pat, expr, span, _recovered) => - visit_visitable!($($mut)? vis, pat, expr, span), + visit_visitable!(vis, pat, expr, span), ExprKind::If(head_expression, if_block, optional_else) => - visit_visitable!($($mut)? vis, head_expression, if_block, optional_else), + visit_visitable!(vis, head_expression, if_block, optional_else), ExprKind::While(subexpression, block, opt_label) => - visit_visitable!($($mut)? vis, subexpression, block, opt_label), + visit_visitable!(vis, subexpression, block, opt_label), ExprKind::ForLoop(ForLoop { pat, iter, body, label, kind }) => - visit_visitable!($($mut)? vis, pat, iter, body, label, kind), + visit_visitable!(vis, pat, iter, body, label, kind), ExprKind::Loop(block, opt_label, span) => - visit_visitable!($($mut)? vis, block, opt_label, span), + visit_visitable!(vis, block, opt_label, span), ExprKind::Match(subexpression, arms, kind) => - visit_visitable!($($mut)? vis, subexpression, arms, kind), + visit_visitable!(vis, subexpression, arms, kind), ExprKind::Closure(Closure { binder, capture_clause, @@ -1005,73 +1005,73 @@ macro_rules! common_visitor_and_walkers { fn_decl_span, fn_arg_span, }) => { - visit_visitable!($($mut)? vis, constness, movability, capture_clause); + visit_visitable!(vis, constness, movability, capture_clause); let kind = FnKind::Closure(binder, coroutine_marker, fn_decl, body); try_visit!(vis.visit_fn(kind, attrs, *span, *id)); - visit_visitable!($($mut)? vis, fn_decl_span, fn_arg_span); + visit_visitable!(vis, fn_decl_span, fn_arg_span); } ExprKind::Block(block, opt_label) => - visit_visitable!($($mut)? vis, block, opt_label), + visit_visitable!(vis, block, opt_label), ExprKind::Gen(capt, body, kind, decl_span) => - visit_visitable!($($mut)? vis, capt, body, kind, decl_span), + visit_visitable!(vis, capt, body, kind, decl_span), ExprKind::Await(expr, span) | ExprKind::Move(expr, span) | ExprKind::Use(expr, span) => - visit_visitable!($($mut)? vis, expr, span), + visit_visitable!(vis, expr, span), ExprKind::Assign(lhs, rhs, span) => - visit_visitable!($($mut)? vis, lhs, rhs, span), + visit_visitable!(vis, lhs, rhs, span), ExprKind::AssignOp(op, lhs, rhs) => - visit_visitable!($($mut)? vis, op, lhs, rhs), + visit_visitable!(vis, op, lhs, rhs), ExprKind::Field(subexpression, ident) => - visit_visitable!($($mut)? vis, subexpression, ident), + visit_visitable!(vis, subexpression, ident), ExprKind::Index(main_expression, index_expression, span) => - visit_visitable!($($mut)? vis, main_expression, index_expression, span), + visit_visitable!(vis, main_expression, index_expression, span), ExprKind::Range(start, end, limit) => - visit_visitable!($($mut)? vis, start, end, limit), + visit_visitable!(vis, start, end, limit), ExprKind::Underscore => {} ExprKind::Path(maybe_qself, path) => - visit_visitable!($($mut)? vis, maybe_qself, path), + visit_visitable!(vis, maybe_qself, path), ExprKind::Break(opt_label, opt_expr) => - visit_visitable!($($mut)? vis, opt_label, opt_expr), + visit_visitable!(vis, opt_label, opt_expr), ExprKind::Continue(opt_label) => - visit_visitable!($($mut)? vis, opt_label), + visit_visitable!(vis, opt_label), ExprKind::Ret(optional_expression) | ExprKind::Yeet(optional_expression) => - visit_visitable!($($mut)? vis, optional_expression), + visit_visitable!(vis, optional_expression), ExprKind::Become(expr) => - visit_visitable!($($mut)? vis, expr), + visit_visitable!(vis, expr), ExprKind::MacCall(mac) => - visit_visitable!($($mut)? vis, mac), + visit_visitable!(vis, mac), ExprKind::Paren(subexpression) => - visit_visitable!($($mut)? vis, subexpression), + visit_visitable!(vis, subexpression), ExprKind::InlineAsm(asm) => - visit_visitable!($($mut)? vis, asm), + visit_visitable!(vis, asm), ExprKind::FormatArgs(f) => - visit_visitable!($($mut)? vis, f), + visit_visitable!(vis, f), ExprKind::OffsetOf(container, fields) => - visit_visitable!($($mut)? vis, container, fields), + visit_visitable!(vis, container, fields), ExprKind::Yield(kind) => - visit_visitable!($($mut)? vis, kind), + visit_visitable!(vis, kind), ExprKind::Try(subexpression) => - visit_visitable!($($mut)? vis, subexpression), + visit_visitable!(vis, subexpression), ExprKind::TryBlock(body, optional_type) => - visit_visitable!($($mut)? vis, body, optional_type), + visit_visitable!(vis, body, optional_type), ExprKind::Lit(token) => - visit_visitable!($($mut)? vis, token), + visit_visitable!(vis, token), ExprKind::IncludedBytes(bytes) => - visit_visitable!($($mut)? vis, bytes), + visit_visitable!(vis, bytes), ExprKind::UnsafeBinderCast(kind, expr, ty) => - visit_visitable!($($mut)? vis, kind, expr, ty), + visit_visitable!(vis, kind, expr, ty), ExprKind::DirectConstArg(expr) => - visit_visitable!($($mut)? vis, expr), + visit_visitable!(vis, expr), ExprKind::Err(_guar) => {} ExprKind::Dummy => {} } - visit_visitable!($($mut)? vis, span); + visit_visitable!(vis, span); V::Result::output() }); - define_named_walk!($(($mut))? $Visitor$(<$lt>)? + define_named_walk!($Visitor$(<$lt>)? pub fn walk_anon_const(AnonConst); pub fn walk_arm(Arm); //pub fn walk_assoc_item(AssocItem, _ctxt: AssocCtxt); From 2c3f8e938ff2d222537d433201d01f424b29100f Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 2 Sep 2026 16:53:41 +1000 Subject: [PATCH 7/9] Remove a few more `$($mut)?` occurrences Similar to the previous commit. --- compiler/rustc_ast/src/mut_visit.rs | 8 ++++---- compiler/rustc_ast/src/visit.rs | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index e7bf694e4ea5d..3984ac9d60968 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -181,7 +181,7 @@ macro_rules! impl_walkable { } macro_rules! impl_visitable_noop { - ( $($ty:ty,)*) => { + ($($ty:ty,)*) => { $( impl_visitable!(|&mut self: $ty, _vis: &mut V, _extra: ()| {}); )* @@ -189,7 +189,7 @@ macro_rules! impl_visitable_noop { } macro_rules! impl_visitable_list { - ( $($ty:ty,)*) => { + ($($ty:ty,)*) => { $(impl MutVisitable for $ty where for<'a> &'a mut $ty: IntoIterator, @@ -208,7 +208,7 @@ macro_rules! impl_visitable_list { } macro_rules! impl_visitable_direct { - ( $($ty:ty,)*) => { + ($($ty:ty,)*) => { $(impl_visitable!( |&mut self: $ty, visitor: &mut V, _extra: ()| { MutWalkable::walk_mut(self, visitor) @@ -218,7 +218,7 @@ macro_rules! impl_visitable_direct { } macro_rules! impl_visitable_calling_walkable { - ( + ( $( fn $method:ident($ty:ty $(, $extra_name:ident: $extra_ty:ty)?); )* ) => { $(fn $method(&mut self, node: &mut $ty $(, $extra_name:$extra_ty)?) { diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index d160c2e87badb..4aa05e6cb2dbb 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -343,7 +343,7 @@ macro_rules! common_visitor_and_walkers { } // This macro generates `impl Visitable` and `impl MutVisitable` that do nothing. - impl_visitable_noop!(<$($lt)? $($mut)?> + impl_visitable_noop!($(<$lt>)? AttrId, bool, rustc_span::ByteSymbol, @@ -372,7 +372,7 @@ macro_rules! common_visitor_and_walkers { // 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)?> + impl_visitable_list!($(<$lt>)? ThinVec, ThinVec, ThinVec, @@ -393,7 +393,7 @@ macro_rules! common_visitor_and_walkers { // 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)?> + impl_visitable_direct!($(<$lt>)? AngleBracketedArg, AngleBracketedArgs, AsmMacro, @@ -546,7 +546,7 @@ macro_rules! common_visitor_and_walkers { // 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)?> + impl_visitable_calling_walkable!($(<$lt>)? fn visit_anon_const(AnonConst); fn visit_arm(Arm); //fn visit_assoc_item(AssocItem, _ctxt: AssocCtxt); @@ -765,7 +765,7 @@ macro_rules! common_visitor_and_walkers { } V::Result::output() });)? - $(impl_visitable_list!(<$mut> ThinVec<(UseTree, NodeId)>,);)? + $(${ignore($mut)} impl_visitable_list!(ThinVec<(UseTree, NodeId)>,);)? fn walk_item_inner<$($lt,)? K: WalkItemKind, V: $Visitor$(<$lt>)?>( visitor: &mut V, From ebec21bb020f231f28cf134e9da7a5a76385067f Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 2 Sep 2026 21:59:43 +1000 Subject: [PATCH 8/9] Streamline `generate_*_fns` `generate_list_visit_fns` currently creates two functions for each case: the method `MutVisitable::visit_mut` and the free function `$name`, of the form `visit_foo`. The former calls the latter. But the latter is a single line of code and can be easily inlined into the former and removed. This avoids the need to provide `$name`. The commit also changes the argument order so each case's `$visit_fn` comes before the type, because that feels more natural. It's a similar story for `generate_flat_map_visit_fns`. Also, only support a single optional argument in these macros, (a) because that's all that is needed and (b) to match all the other macros. --- compiler/rustc_ast/src/mut_visit.rs | 48 ++++++++++----------------- compiler/rustc_ast/src/visit.rs | 50 +++++++++++------------------ 2 files changed, 35 insertions(+), 63 deletions(-) diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 3984ac9d60968..66d57b3efa9b1 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -244,49 +244,35 @@ macro_rules! define_named_walk { super::common_visitor_and_walkers!((mut) MutVisitor); macro_rules! generate_flat_map_visitor_fns { - ($($name:ident, $Ty:ty, $flat_map_fn:ident$(, $param:ident: $ParamTy:ty)*;)+) => { + ($($flat_map_fn:ident, $Ty:ty $(, $param:ident: $ParamTy:ty)?;)+) => { $( #[allow(unused_parens)] impl MutVisitable for ThinVec<$Ty> { - type Extra = ($($ParamTy),*); + type Extra = ($($ParamTy)?); #[inline] - fn visit_mut( - &mut self, - visitor: &mut V, - ($($param),*): Self::Extra, - ) -> V::Result { - $name(visitor, self $(, $param)*) + fn visit_mut(&mut self, visitor: &mut V, ($($param)?): Self::Extra) -> V::Result { + self.flat_map_in_place(|value| visitor.$flat_map_fn(value $(, $param)?)); } } - - fn $name( - vis: &mut V, - values: &mut ThinVec<$Ty>, - $( - $param: $ParamTy, - )* - ) { - values.flat_map_in_place(|value| vis.$flat_map_fn(value$(,$param)*)); - } )+ } } generate_flat_map_visitor_fns! { - visit_items, Box, flat_map_item; - visit_foreign_items, Box, flat_map_foreign_item; - visit_generic_params, GenericParam, flat_map_generic_param; - visit_stmts, Stmt, flat_map_stmt; - visit_exprs, Box, filter_map_expr; - visit_expr_fields, ExprField, flat_map_expr_field; - visit_pat_fields, PatField, flat_map_pat_field; - visit_variants, Variant, flat_map_variant; - visit_assoc_items, Box, flat_map_assoc_item, ctxt: AssocCtxt; - visit_where_predicates, WherePredicate, flat_map_where_predicate; - visit_params, Param, flat_map_param; - visit_field_defs, FieldDef, flat_map_field_def; - visit_arms, Arm, flat_map_arm; + flat_map_item, Box; + flat_map_foreign_item, Box; + flat_map_generic_param, GenericParam; + flat_map_stmt, Stmt; + filter_map_expr, Box; // the odd one out; it works because `Option` impls `IntoIterator` + flat_map_expr_field, ExprField; + flat_map_pat_field, PatField; + flat_map_variant, Variant; + flat_map_assoc_item, Box, ctxt: AssocCtxt; + flat_map_where_predicate, WherePredicate; + flat_map_param, Param; + flat_map_field_def, FieldDef; + flat_map_arm, Arm; } pub fn walk_flat_map_pat_field( diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 4aa05e6cb2dbb..65a672df06933 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -1137,50 +1137,36 @@ macro_rules! common_visitor_and_walkers { common_visitor_and_walkers!(Visitor<'a>); macro_rules! generate_list_visit_fns { - ($($name:ident, $Ty:ty, $visit_fn:ident$(, $param:ident: $ParamTy:ty)*;)+) => { + ($($visit_fn:ident, $Ty:ty $(, $param:ident: $ParamTy:ty)?;)+) => { $( #[allow(unused_parens)] impl<'a, V: Visitor<'a>> Visitable<'a, V> for ThinVec<$Ty> { - type Extra = ($($ParamTy),*); + type Extra = ($($ParamTy)?); #[inline] - fn visit( - &'a self, - visitor: &mut V, - ($($param),*): Self::Extra, - ) -> V::Result { - $name(visitor, self $(, $param)*) + fn visit(&'a self, visitor: &mut V, ($($param)?): Self::Extra) -> V::Result { + walk_list!(visitor, $visit_fn, self $(, $param)?); + V::Result::output() } } - - 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, visit_item; - visit_foreign_items, Box, visit_foreign_item; - visit_generic_params, GenericParam, visit_generic_param; - visit_stmts, Stmt, visit_stmt; - visit_exprs, Box, 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, 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; + visit_item, Box; + visit_foreign_item, Box; + visit_generic_param, GenericParam; + visit_stmt, Stmt; + visit_expr, Box; + visit_expr_field, ExprField; + visit_pat_field, PatField; + visit_variant, Variant; + visit_assoc_item, Box, ctxt: AssocCtxt; + visit_where_predicate, WherePredicate; + visit_param, Param; + visit_field_def, FieldDef; + visit_arm, Arm; } pub fn walk_stmt<'a, V: Visitor<'a>>(visitor: &mut V, statement: &'a Stmt) -> V::Result { From e61c7c4f0cf314ac723f197ae1468b60cbcb7702 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 3 Sep 2026 09:23:32 +1000 Subject: [PATCH 9/9] Improve formatting Must be done manually because rustfmt doesn't do much within macro definitions. Also, the code currently has a mix of `&$($mut)? $($lt)?` and `&$($lt)? $($mut)?` pairs. The inconsistency doesn't matter because only one of `$mut` and `$lt` is ever present. But this commit changes them all to the latter form for consistency. --- compiler/rustc_ast/src/mut_visit.rs | 6 ++- compiler/rustc_ast/src/visit.rs | 62 ++++++++++++++++++++--------- 2 files changed, 49 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 66d57b3efa9b1..41d432cb00069 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -285,7 +285,11 @@ pub fn walk_flat_map_pat_field( macro_rules! generate_walk_flat_map_fns { ($($fn_name:ident($Ty:ty$(,$extra_name:ident: $ExtraTy:ty)*) => $visit_fn_name:ident;)+) => {$( - pub fn $fn_name(vis: &mut V, mut value: $Ty$(,$extra_name: $ExtraTy)*) -> SmallVec<[$Ty; 1]> { + pub fn $fn_name( + vis: &mut V, + mut value: $Ty + $(,$extra_name: $ExtraTy)* + ) -> SmallVec<[$Ty; 1]> { vis.$visit_fn_name(&mut value$(,$extra_name)*); smallvec![value] } diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 65a672df06933..adc211ce6a790 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -308,7 +308,7 @@ macro_rules! common_visitor_and_walkers { &'a $($mut)? ClosureBinder, &'a $($mut)? Option, &'a $($mut)? Box, - &'a $($mut)? Box + &'a $($mut)? Box, ), } @@ -490,7 +490,11 @@ macro_rules! common_visitor_and_walkers { /// 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`.")] + #[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 @@ -500,7 +504,7 @@ macro_rules! common_visitor_and_walkers { /// 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)? { + pub trait $Visitor<$($lt)?>: Sized $(${ignore($mut)} + MutVisitorResult)? { $( ${ignore($lt)} /// The result type of the `visit_*` methods. Can be either `()`, @@ -535,7 +539,9 @@ macro_rules! common_visitor_and_walkers { // 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 { + 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) }); @@ -643,7 +649,9 @@ macro_rules! common_visitor_and_walkers { walk_item(self, item) } - fn visit_assoc_item(&mut self, item: &$($lt)? $($mut)? AssocItem, ctxt: AssocCtxt) -> Self::Result { + 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) }); @@ -667,7 +675,9 @@ macro_rules! common_visitor_and_walkers { walk_stmt(self, s) } - fn visit_nested_use_tree(&mut self, use_tree: &$lt UseTree, id: NodeId) -> Self::Result { + 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) } @@ -685,7 +695,9 @@ macro_rules! common_visitor_and_walkers { // Do nothing. } - fn flat_map_foreign_item(&mut self, ni: Box) -> SmallVec<[Box; 1]> { + fn flat_map_foreign_item(&mut self, ni: Box) + -> SmallVec<[Box; 1]> + { walk_flat_map_foreign_item(self, ni) } @@ -725,7 +737,9 @@ macro_rules! common_visitor_and_walkers { walk_flat_map_param(self, param) } - fn flat_map_generic_param(&mut self, param: GenericParam) -> SmallVec<[GenericParam; 1]> { + fn flat_map_generic_param(&mut self, param: GenericParam) + -> SmallVec<[GenericParam; 1]> + { walk_flat_map_generic_param(self, param) } @@ -769,7 +783,7 @@ macro_rules! common_visitor_and_walkers { fn walk_item_inner<$($lt,)? K: WalkItemKind, V: $Visitor$(<$lt>)?>( visitor: &mut V, - item: &$($mut)? $($lt)? Item, + item: &$($lt)? $($mut)? Item, ctxt: K::Ctxt, ) -> V::Result { let Item { attrs, id, kind, vis, span, tokens: _ } = item; @@ -782,7 +796,7 @@ macro_rules! common_visitor_and_walkers { // Do not implement `Walkable`/`MutWalkable` for *Item to avoid confusion. pub fn walk_item<$($lt,)? K: WalkItemKind, V: $Visitor$(<$lt>)?>( visitor: &mut V, - item: &$($mut)? $($lt)? Item, + item: &$($lt)? $($mut)? Item, ) -> V::Result { walk_item_inner(visitor, item, ()) } @@ -790,7 +804,7 @@ macro_rules! common_visitor_and_walkers { // Do not implement `Walkable`/`MutWalkable` for *Item to avoid confusion. pub fn walk_assoc_item<$($lt,)? K: WalkItemKind, V: $Visitor$(<$lt>)?>( visitor: &mut V, - item: &$($mut)? $($lt)? Item, + item: &$($lt)? $($mut)? Item, ctxt: AssocCtxt, ) -> V::Result { walk_item_inner(visitor, item, ctxt) @@ -839,7 +853,7 @@ macro_rules! common_visitor_and_walkers { visit_visitable!(vis, impl_), ItemKind::Trait(trait_) => visit_visitable!(vis, trait_), - ItemKind::TraitAlias(TraitAlias { constness, ident, generics, bounds}) => { + ItemKind::TraitAlias(TraitAlias { constness, ident, generics, bounds }) => { visit_visitable!(vis, constness, ident, generics); visit_visitable_with!(vis, bounds, BoundKind::Bound) } @@ -904,7 +918,7 @@ macro_rules! common_visitor_and_walkers { ForeignItemKind::Static(item) => visit_visitable!(vis, item), ForeignItemKind::Fn(func) => { - let kind = FnKind::Fn(FnCtxt::Foreign, visibility, &$($mut)?*func); + let kind = FnKind::Fn(FnCtxt::Foreign, visibility, &$($mut)? *func); try_visit!(vis.visit_fn(kind, attrs, span, id)) } ForeignItemKind::TyAlias(alias) => @@ -916,13 +930,25 @@ macro_rules! common_visitor_and_walkers { } } - pub fn walk_fn<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, kind: FnKind<$($lt)? $(${ignore($mut)} '_)?>) -> V::Result { + 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, eii_impl }, + Fn { + defaultness, + ident, + sig, + generics, + contract, + body, + define_opaque, + eii_impl, + }, ) => { let FnSig { header, decl, span } = sig; visit_visitable!(vis, @@ -936,7 +962,7 @@ macro_rules! common_visitor_and_walkers { V::Result::output() } - impl_walkable!(|&$($mut)? $($lt)? self: Impl, vis: &mut V| { + impl_walkable!(|&$($lt)? $($mut)? self: Impl, vis: &mut V| { let Impl { generics, of_trait, self_ty, items, constness: _ } = self; try_visit!(vis.visit_generics(generics)); if let Some(of_trait) = of_trait { @@ -949,14 +975,14 @@ macro_rules! common_visitor_and_walkers { }); // Special case to call `visit_method_receiver_expr`. - impl_walkable!(|&$($mut)? $($lt)? self: MethodCall, vis: &mut V| { + impl_walkable!(|&$($lt)? $($mut)? self: MethodCall, vis: &mut V| { let MethodCall { seg, receiver, args, span } = self; try_visit!(vis.visit_method_receiver_expr(receiver)); visit_visitable!(vis, seg, args, span); V::Result::output() }); - impl_walkable!(|&$($mut)? $($lt)? self: Expr, vis: &mut V| { + impl_walkable!(|&$($lt)? $($mut)? self: Expr, vis: &mut V| { let Expr { id, kind, span, attrs, tokens: _ } = self; visit_visitable!(vis, id, attrs); match kind {