From 53ed560f1902d6f249771eef4bccc51c79059d24 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 3 Sep 2026 11:25:14 +1000 Subject: [PATCH 01/11] Add missing `walk_test_binder_constraints` method `visit_test_binder_constraints` is the only `visit_foo` method in `impl_visitable_calling_walkable!` without a corresponding `walk_foo` method in `define_named_walk!`. I confirmed with the original author (khyperia) that this is an unintentional oversight. --- compiler/rustc_ast/src/visit.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 14ef1c147f253..8c1e5fd04afd1 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -1145,8 +1145,9 @@ macro_rules! common_visitor_and_walkers { pub fn walk_precise_capturing_arg(PreciseCapturingArg); pub fn walk_qself(QSelf); pub fn walk_test_binder_body(TestBinderBody); - pub fn walk_test_binder_constraint(TestBinderConstraint); pub fn walk_test_binder_bound_type_constraint(TestBinderBoundTypeConstraint); + pub fn walk_test_binder_constraint(TestBinderConstraint); + pub fn walk_test_binder_constraints(TestBinderConstraints); pub fn walk_test_binder_exists(TestBinderExists); pub fn walk_test_binder_forall(TestBinderForall); pub fn walk_trait_ref(TraitRef); From 230a513c205dcc3c3a3e40dc617af29081fcc017 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 3 Sep 2026 11:30:27 +1000 Subject: [PATCH 02/11] Introduce `for_each_ast_visit_hook` There is currently a big list of `visit_*` methods in one macro call and another list of `walk_*` method in another macro call. The previous commit showed these can unintentionally get out of sync. This commit introduces a higher-order macro that puts all the information in a single place. This will make it impossible for the `visit_*` and `walk_*` methods to get out of sync (as we saw in the previous commit). It will also facilitate another cleanup in the next commit. --- compiler/rustc_ast/src/mut_visit.rs | 12 +- compiler/rustc_ast/src/visit.rs | 219 +++++++++++----------------- 2 files changed, 92 insertions(+), 139 deletions(-) diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 41d432cb00069..80c6eb9fad3fd 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -218,13 +218,13 @@ macro_rules! impl_visitable_direct { } macro_rules! impl_visitable_calling_walkable { - ( - $( fn $method:ident($ty:ty $(, $extra_name:ident: $extra_ty:ty)?); )* + ($Visitor:ident + $( $visit:ident($ty:ty $(, $extra_name:ident: $extra_ty:ty)?) => $walk:ident; )* ) => { - $(fn $method(&mut self, node: &mut $ty $(, $extra_name:$extra_ty)?) { + $(fn $visit(&mut self, node: &mut $ty $(, $extra_name: $extra_ty)?) { impl_visitable!(|&mut self: $ty, visitor: &mut V, extra: ($($extra_ty)?)| { let ($($extra_name)?) = extra; - visitor.$method(self $(, $extra_name)?); + visitor.$visit(self $(, $extra_name)?); }); MutWalkable::walk_mut(node, self) })* @@ -233,9 +233,9 @@ macro_rules! impl_visitable_calling_walkable { macro_rules! define_named_walk { ($Visitor:ident - $( pub fn $method:ident($ty:ty); )* + $( $visit:ident($ty:ty $(, $extra_name:ident: $extra_ty:ty)?) => $walk:ident; )* ) => { - $(pub fn $method(visitor: &mut V, node: &mut $ty) { + $(pub fn $walk(visitor: &mut V, node: &mut $ty) { MutWalkable::walk_mut(node, visitor) })* }; diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 8c1e5fd04afd1..3173e79ba383a 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -269,13 +269,13 @@ macro_rules! impl_visitable_direct { } macro_rules! impl_visitable_calling_walkable { - (<$lt:lifetime> - $( fn $method:ident($ty:ty $(, $extra_name:ident: $extra_ty:ty)?); )* + ($Visitor:ident<$lt:lifetime> + $( $visit:ident($ty:ty $(, $extra_name:ident: $extra_ty:ty)?) => $walk:ident; )* ) => { - $(fn $method(&mut self, node: &$lt $ty $(, $extra_name:$extra_ty)?) -> Self::Result { + $(fn $visit(&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)?) + visitor.$visit(self $(, $extra_name)?) }); Walkable::walk_ref(node, self) })* @@ -284,11 +284,89 @@ macro_rules! impl_visitable_calling_walkable { macro_rules! define_named_walk { ($Visitor:ident<$lt:lifetime> - $( pub fn $method:ident($ty:ty); )* + $( $visit:ident($ty:ty $(, $extra_name:ident: $extra_ty:ty)?) => $walk:ident; )* ) => { - $(pub fn $method<$lt, V: $Visitor<$lt>>(visitor: &mut V, node: &$lt $ty) -> V::Result { + $(pub fn $walk<$lt, V: $Visitor<$lt>>(visitor: &mut V, node: &$lt $ty) -> V::Result { Walkable::walk_ref(node, visitor) })* + } +} + +/// Higher-order macro that puts all the visit/walk hook information in a single place. The +/// passed-in macro should have a left hand side like this: +/// ```ignore (partial) +/// ($Visitor:ident +/// $( $visit:ident($ty:ty $(, $extra_name:ident: $extra_ty:ty)?) => $walk:ident; )* +/// ) => ... +/// ``` +#[macro_export] +macro_rules! for_each_ast_visit_hook { + ($Visitor:ident$(<$lt:lifetime>)? + $macro:ident! + ) => { + $macro!($Visitor$(<$lt>)? + visit_anon_const(AnonConst) => walk_anon_const; + visit_arm(Arm) => walk_arm; + //visit_assoc_item(AssocItem, _ctxt: AssocCtxt) => walk_assoc_item; + visit_assoc_item_constraint(AssocItemConstraint) => walk_assoc_item_constraint; + visit_attribute(Attribute) => walk_attribute; + visit_block(Block) => walk_block; + //visit_nested_use_tree((UseTree, NodeId)) => walk_nested_use_tree; + visit_capture_by(CaptureBy) => walk_capture_by; + visit_closure_binder(ClosureBinder) => walk_closure_binder; + visit_contract(FnContract) => walk_contract; + visit_coroutine_marker(CoroutineMarker) => walk_coroutine_marker; + visit_crate(Crate) => walk_crate; + visit_expr(Expr) => walk_expr; + visit_expr_field(ExprField) => walk_expr_field; + visit_field_def(FieldDef) => walk_field_def; + visit_field_def_extras(FieldDefExtras) => walk_field_def_extras; + visit_fn_decl(FnDecl) => walk_fn_decl; + visit_fn_header(FnHeader) => walk_fn_header; + visit_fn_ret_ty(FnRetTy) => walk_fn_ret_ty; + //visit_foreign_item(ForeignItem) => walk_foreign_item; + visit_foreign_mod(ForeignMod) => walk_foreign_mod; + visit_format_args(FormatArgs) => walk_format_args; + visit_generic_arg(GenericArg) => walk_generic_arg; + visit_generic_args(GenericArgs) => walk_generic_args; + visit_generic_param(GenericParam) => walk_generic_param; + visit_generics(Generics) => walk_generics; + visit_inline_asm(InlineAsm) => walk_inline_asm; + visit_inline_asm_sym(InlineAsmSym) => walk_inline_asm_sym; + visit_impl_restriction(ImplRestriction) => walk_impl_restriction; + //visit_item(Item) => walk_item; + visit_label(Label) => walk_label; + visit_lifetime(Lifetime, _ctxt: LifetimeCtxt) => walk_lifetime; + visit_local(Local) => walk_local; + visit_mac_call(MacCall) => walk_mac; + visit_macro_def(MacroDef) => walk_macro_def; + visit_mut_restriction(MutRestriction) => walk_mut_restriction; + visit_param_bound(GenericBound, _ctxt: BoundKind) => walk_param_bound; + visit_param(Param) => walk_param; + visit_pat_field(PatField) => walk_pat_field; + visit_path(Path) => walk_path; + visit_path_segment(PathSegment) => walk_path_segment; + visit_pat(Pat) => walk_pat; + visit_poly_trait_ref(PolyTraitRef) => walk_poly_trait_ref; + visit_precise_capturing_arg(PreciseCapturingArg) => walk_precise_capturing_arg; + visit_qself(QSelf) => walk_qself; + visit_test_binder_body(TestBinderBody) => walk_test_binder_body; + visit_test_binder_bound_type_constraint(TestBinderBoundTypeConstraint) => + walk_test_binder_bound_type_constraint; + visit_test_binder_constraint(TestBinderConstraint) => walk_test_binder_constraint; + visit_test_binder_constraints(TestBinderConstraints) => walk_test_binder_constraints; + visit_test_binder_exists(TestBinderExists) => walk_test_binder_exists; + visit_test_binder_forall(TestBinderForall) => walk_test_binder_forall; + visit_trait_ref(TraitRef) => walk_trait_ref; + visit_ty_pat(TyPat) => walk_ty_pat; + visit_ty(Ty) => walk_ty; + visit_use_tree(UseTree) => walk_use_tree; + visit_variant_data(VariantData) => walk_variant_data; + visit_variant(Variant) => walk_variant; + visit_vis(Visibility) => walk_vis; + visit_where_predicate_kind(WherePredicateKind) => walk_where_predicate_kind; + visit_where_predicate(WherePredicate) => walk_where_predicate; + ); }; } @@ -549,71 +627,7 @@ macro_rules! common_visitor_and_walkers { Self::Result::output() } - // 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>)? - 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_marker(CoroutineMarker); - fn visit_crate(Crate); - fn visit_expr(Expr); - fn visit_expr_field(ExprField); - fn visit_field_def(FieldDef); - fn visit_field_def_extras(FieldDefExtras); - 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_impl_restriction(ImplRestriction); - //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_mut_restriction(MutRestriction); - 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_test_binder_body(TestBinderBody); - fn visit_test_binder_constraint(TestBinderConstraint); - fn visit_test_binder_bound_type_constraint(TestBinderBoundTypeConstraint); - fn visit_test_binder_constraints(TestBinderConstraints); - fn visit_test_binder_exists(TestBinderExists); - fn visit_test_binder_forall(TestBinderForall); - 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); - ); + crate::for_each_ast_visit_hook!($Visitor$(<$lt>)? impl_visitable_calling_walkable!); // We want `Visitor` to take the `NodeId` by value. fn visit_id(&mut self, _id: $(&$mut)? NodeId) -> Self::Result { @@ -1098,68 +1112,7 @@ macro_rules! common_visitor_and_walkers { V::Result::output() }); - define_named_walk!($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_marker(CoroutineMarker); - 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_field_def_extras(FieldDefExtras); - 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_impl_restriction(ImplRestriction); - //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_mut_restriction(MutRestriction); - 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_test_binder_body(TestBinderBody); - pub fn walk_test_binder_bound_type_constraint(TestBinderBoundTypeConstraint); - pub fn walk_test_binder_constraint(TestBinderConstraint); - pub fn walk_test_binder_constraints(TestBinderConstraints); - pub fn walk_test_binder_exists(TestBinderExists); - pub fn walk_test_binder_forall(TestBinderForall); - 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); - ); + crate::for_each_ast_visit_hook!($Visitor$(<$lt>)? define_named_walk!); }; } From e4f0df474723939b236a712934c9798278572fa8 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 3 Sep 2026 11:42:48 +1000 Subject: [PATCH 03/11] Hoist impls out of fns Currently various `Visitable` impls are defined within functions even though `Visitable` is defined at the top level, which is weird and requires `allow(non_local_definitions)`. This commit uses `for_each_ast_visit_hook` to move them out. It also renames a couple of the existing macros to give them simpler names. --- compiler/rustc_ast/src/mut_visit.rs | 21 ++++--- compiler/rustc_ast/src/visit.rs | 85 +++++++++++++++++------------ 2 files changed, 65 insertions(+), 41 deletions(-) diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 80c6eb9fad3fd..ab52abab72fa2 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -159,7 +159,7 @@ macro_rules! impl_visitable { (|&mut $self:ident: $self_ty:ty, $vis:ident: &mut $vis_ty:ident, $extra:ident: $extra_ty:ty| $block:block) => { - #[allow(unused_parens, non_local_definitions)] + #[allow(unused_parens)] impl<$vis_ty: MutVisitor> MutVisitable<$vis_ty> for $self_ty { type Extra = $extra_ty; fn visit_mut(&mut $self, $vis: &mut $vis_ty, $extra: Self::Extra) -> V::Result { @@ -217,21 +217,28 @@ macro_rules! impl_visitable_direct { } } -macro_rules! impl_visitable_calling_walkable { +macro_rules! fn_visit { ($Visitor:ident $( $visit:ident($ty:ty $(, $extra_name:ident: $extra_ty:ty)?) => $walk:ident; )* ) => { $(fn $visit(&mut self, node: &mut $ty $(, $extra_name: $extra_ty)?) { - impl_visitable!(|&mut self: $ty, visitor: &mut V, extra: ($($extra_ty)?)| { - let ($($extra_name)?) = extra; - visitor.$visit(self $(, $extra_name)?); - }); MutWalkable::walk_mut(node, self) })* } } -macro_rules! define_named_walk { +macro_rules! impl_visitable_visit { + ($Visitor:ident + $( $visit:ident($ty:ty $(, $extra_name:ident: $extra_ty:ty)?) => $walk:ident; )* + ) => { + $(impl_visitable!(|&mut self: $ty, visitor: &mut V, extra: ($($extra_ty)?)| { + let ($($extra_name)?) = extra; + visitor.$visit(self $(, $extra_name)?); + });)* + } +} + +macro_rules! fn_walk { ($Visitor:ident $( $visit:ident($ty:ty $(, $extra_name:ident: $extra_ty:ty)?) => $walk:ident; )* ) => { diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 3173e79ba383a..bf4c3de3a3e13 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -207,7 +207,7 @@ 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)] + #[allow(unused_parens)] 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 { @@ -268,21 +268,28 @@ macro_rules! impl_visitable_direct { }; } -macro_rules! impl_visitable_calling_walkable { +macro_rules! fn_visit { ($Visitor:ident<$lt:lifetime> $( $visit:ident($ty:ty $(, $extra_name:ident: $extra_ty:ty)?) => $walk:ident; )* ) => { $(fn $visit(&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.$visit(self $(, $extra_name)?) - }); Walkable::walk_ref(node, self) })* }; } -macro_rules! define_named_walk { +macro_rules! impl_visitable_visit { + ($Visitor:ident<$lt:lifetime> + $( $visit:ident($ty:ty $(, $extra_name:ident: $extra_ty:ty)?) => $walk:ident; )* + ) => { + $(impl_visitable!(|&$lt self: $ty, visitor: &mut V, extra: ($($extra_ty)?)| { + let ($($extra_name)?) = extra; + visitor.$visit(self $(, $extra_name)?) + });)* + }; +} + +macro_rules! fn_walk { ($Visitor:ident<$lt:lifetime> $( $visit:ident($ty:ty $(, $extra_name:ident: $extra_ty:ty)?) => $walk:ident; )* ) => { @@ -620,27 +627,14 @@ macro_rules! common_visitor_and_walkers { 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_visitable!(self, span); Self::Result::output() } - crate::for_each_ast_visit_hook!($Visitor$(<$lt>)? impl_visitable_calling_walkable!); + crate::for_each_ast_visit_hook!($Visitor$(<$lt>)? fn_visit!); // 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() } @@ -651,25 +645,16 @@ macro_rules! common_visitor_and_walkers { } 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) } @@ -704,9 +689,6 @@ macro_rules! common_visitor_and_walkers { // 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. } @@ -775,6 +757,41 @@ macro_rules! common_visitor_and_walkers { )? } + crate::for_each_ast_visit_hook!($Visitor$(<$lt>)? impl_visitable_visit!); + + impl_visitable!(|&$($lt)? $($mut)? self: Ident, visitor: &mut V, _extra: ()| { + visitor.visit_ident(self) + }); + + $( + 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) + } + ); + + impl_visitable!(|&mut self: Span, visitor: &mut V, _extra: ()| { + visitor.visit_span(self) + }); + )? + + impl_visitable!(|&$($lt)? $($mut)? self: Item, vis: &mut V, _extra: ()| { + vis.visit_item(self) + }); + impl_visitable!(|&$($lt)? $($mut)? self: ForeignItem, vis: &mut V, _extra: ()| { + vis.visit_foreign_item(self) + }); + impl_visitable!(|&$($lt)? $($mut)? self: AssocItem, vis: &mut V, ctxt: AssocCtxt| { + vis.visit_assoc_item(self, ctxt) + }); + pub trait WalkItemKind { type Ctxt; fn walk<$($lt,)? V: $Visitor$(<$lt>)?>( @@ -1112,7 +1129,7 @@ macro_rules! common_visitor_and_walkers { V::Result::output() }); - crate::for_each_ast_visit_hook!($Visitor$(<$lt>)? define_named_walk!); + crate::for_each_ast_visit_hook!($Visitor$(<$lt>)? fn_walk!); }; } From 42b5930e698f96fc3e320891941cd1476fc00072 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 3 Sep 2026 14:14:26 +1000 Subject: [PATCH 04/11] Improve naming consistency Use `$ty` and `$extra` and `$extra_ty` consistently in macros, rather than `$Ty` and `$ExtraTy` and `$ParamTy`. Also fix some spacing. --- compiler/rustc_ast/src/mut_visit.rs | 32 ++++++++++++++--------------- compiler/rustc_ast/src/visit.rs | 24 +++++++++++----------- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index ab52abab72fa2..a029af3a5309d 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -219,9 +219,9 @@ macro_rules! impl_visitable_direct { macro_rules! fn_visit { ($Visitor:ident - $( $visit:ident($ty:ty $(, $extra_name:ident: $extra_ty:ty)?) => $walk:ident; )* + $( $visit:ident($ty:ty $(, $extra:ident: $extra_ty:ty)?) => $walk:ident; )* ) => { - $(fn $visit(&mut self, node: &mut $ty $(, $extra_name: $extra_ty)?) { + $(fn $visit(&mut self, node: &mut $ty $(, $extra: $extra_ty)?) { MutWalkable::walk_mut(node, self) })* } @@ -229,18 +229,18 @@ macro_rules! fn_visit { macro_rules! impl_visitable_visit { ($Visitor:ident - $( $visit:ident($ty:ty $(, $extra_name:ident: $extra_ty:ty)?) => $walk:ident; )* + $( $visit:ident($ty:ty $(, $extra:ident: $extra_ty:ty)?) => $walk:ident; )* ) => { $(impl_visitable!(|&mut self: $ty, visitor: &mut V, extra: ($($extra_ty)?)| { - let ($($extra_name)?) = extra; - visitor.$visit(self $(, $extra_name)?); + let ($($extra)?) = extra; + visitor.$visit(self $(, $extra)?); });)* } } macro_rules! fn_walk { ($Visitor:ident - $( $visit:ident($ty:ty $(, $extra_name:ident: $extra_ty:ty)?) => $walk:ident; )* + $( $visit:ident($ty:ty $(, $extra:ident: $extra_ty:ty)?) => $walk:ident; )* ) => { $(pub fn $walk(visitor: &mut V, node: &mut $ty) { MutWalkable::walk_mut(node, visitor) @@ -251,15 +251,15 @@ macro_rules! fn_walk { super::common_visitor_and_walkers!((mut) MutVisitor); macro_rules! generate_flat_map_visitor_fns { - ($($flat_map_fn:ident, $Ty:ty $(, $param:ident: $ParamTy:ty)?;)+) => { + ($($flat_map_fn:ident, $ty:ty $(, $extra:ident: $extra_ty:ty)?;)+) => { $( #[allow(unused_parens)] - impl MutVisitable for ThinVec<$Ty> { - type Extra = ($($ParamTy)?); + impl MutVisitable for ThinVec<$ty> { + type Extra = ($($extra_ty)?); #[inline] - 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 visit_mut(&mut self, visitor: &mut V, ($($extra)?): Self::Extra) -> V::Result { + self.flat_map_in_place(|value| visitor.$flat_map_fn(value $(, $extra)?)); } } )+ @@ -291,13 +291,13 @@ 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;)+) => {$( + ($($fn_name:ident($ty:ty $(, $extra:ident: $extra_ty:ty)?) => $visit_fn_name:ident;)+) => {$( pub fn $fn_name( vis: &mut V, - mut value: $Ty - $(,$extra_name: $ExtraTy)* - ) -> SmallVec<[$Ty; 1]> { - vis.$visit_fn_name(&mut value$(,$extra_name)*); + mut value: $ty + $(, $extra: $extra_ty)? + ) -> SmallVec<[$ty; 1]> { + vis.$visit_fn_name(&mut value$(, $extra)*); smallvec![value] } )+}; diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index bf4c3de3a3e13..01ca3fa2cc926 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -270,9 +270,9 @@ macro_rules! impl_visitable_direct { macro_rules! fn_visit { ($Visitor:ident<$lt:lifetime> - $( $visit:ident($ty:ty $(, $extra_name:ident: $extra_ty:ty)?) => $walk:ident; )* + $( $visit:ident($ty:ty $(, $extra:ident: $extra_ty:ty)?) => $walk:ident; )* ) => { - $(fn $visit(&mut self, node: &$lt $ty $(, $extra_name: $extra_ty)?) -> Self::Result { + $(fn $visit(&mut self, node: &$lt $ty $(, $extra: $extra_ty)?) -> Self::Result { Walkable::walk_ref(node, self) })* }; @@ -280,18 +280,18 @@ macro_rules! fn_visit { macro_rules! impl_visitable_visit { ($Visitor:ident<$lt:lifetime> - $( $visit:ident($ty:ty $(, $extra_name:ident: $extra_ty:ty)?) => $walk:ident; )* + $( $visit:ident($ty:ty $(, $extra:ident: $extra_ty:ty)?) => $walk:ident; )* ) => { $(impl_visitable!(|&$lt self: $ty, visitor: &mut V, extra: ($($extra_ty)?)| { - let ($($extra_name)?) = extra; - visitor.$visit(self $(, $extra_name)?) + let ($($extra)?) = extra; + visitor.$visit(self $(, $extra)?) });)* }; } macro_rules! fn_walk { ($Visitor:ident<$lt:lifetime> - $( $visit:ident($ty:ty $(, $extra_name:ident: $extra_ty:ty)?) => $walk:ident; )* + $( $visit:ident($ty:ty $(, $extra:ident: $extra_ty:ty)?) => $walk:ident; )* ) => { $(pub fn $walk<$lt, V: $Visitor<$lt>>(visitor: &mut V, node: &$lt $ty) -> V::Result { Walkable::walk_ref(node, visitor) @@ -303,7 +303,7 @@ macro_rules! fn_walk { /// passed-in macro should have a left hand side like this: /// ```ignore (partial) /// ($Visitor:ident -/// $( $visit:ident($ty:ty $(, $extra_name:ident: $extra_ty:ty)?) => $walk:ident; )* +/// $( $visit:ident($ty:ty $(, $extra:ident: $extra_ty:ty)?) => $walk:ident; )* /// ) => ... /// ``` #[macro_export] @@ -1136,15 +1136,15 @@ macro_rules! common_visitor_and_walkers { common_visitor_and_walkers!(Visitor<'a>); macro_rules! generate_list_visit_fns { - ($($visit_fn:ident, $Ty:ty $(, $param:ident: $ParamTy:ty)?;)+) => { + ($($visit_fn:ident, $ty:ty $(, $extra:ident: $extra_ty:ty)?;)+) => { $( #[allow(unused_parens)] - impl<'a, V: Visitor<'a>> Visitable<'a, V> for ThinVec<$Ty> { - type Extra = ($($ParamTy)?); + impl<'a, V: Visitor<'a>> Visitable<'a, V> for ThinVec<$ty> { + type Extra = ($($extra_ty)?); #[inline] - fn visit(&'a self, visitor: &mut V, ($($param)?): Self::Extra) -> V::Result { - walk_list!(visitor, $visit_fn, self $(, $param)?); + fn visit(&'a self, visitor: &mut V, ($($extra)?): Self::Extra) -> V::Result { + walk_list!(visitor, $visit_fn, self $(, $extra)?); V::Result::output() } } From 72410d17b2b61410c047a35dcb53151412c99a56 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 3 Sep 2026 15:06:37 +1000 Subject: [PATCH 05/11] Use `impl_visitable!` for the `generate_*_fns` macros They fit the pattern. Also remove `#[inline]` from `impl_visitable_list` for consistency. The visitor is generic so the methods are monomorphized into the calling crate and probably inlined anyway. --- compiler/rustc_ast/src/mut_visit.rs | 16 ++++------------ compiler/rustc_ast/src/visit.rs | 18 +++++------------- 2 files changed, 9 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index a029af3a5309d..de7cf0e9791d4 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -197,7 +197,6 @@ macro_rules! impl_visitable_list { { type Extra = >::Extra; - #[inline] fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra) { for i in self { i.visit_mut(visitor, extra); @@ -252,17 +251,10 @@ super::common_visitor_and_walkers!((mut) MutVisitor); macro_rules! generate_flat_map_visitor_fns { ($($flat_map_fn:ident, $ty:ty $(, $extra:ident: $extra_ty:ty)?;)+) => { - $( - #[allow(unused_parens)] - impl MutVisitable for ThinVec<$ty> { - type Extra = ($($extra_ty)?); - - #[inline] - fn visit_mut(&mut self, visitor: &mut V, ($($extra)?): Self::Extra) -> V::Result { - self.flat_map_in_place(|value| visitor.$flat_map_fn(value $(, $extra)?)); - } - } - )+ + $(impl_visitable!(|&mut self: ThinVec<$ty>, visitor: &mut V, extra: ($($extra_ty)?)| { + let ($($extra)?) = extra; + self.flat_map_in_place(|value| visitor.$flat_map_fn(value $(, $extra)?)); + });)+ } } diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 01ca3fa2cc926..a2861305a7d24 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -247,7 +247,6 @@ macro_rules! impl_visitable_list { { type Extra = >::Extra; - #[inline] fn visit(&$lt self, visitor: &mut V, extra: Self::Extra) -> V::Result { for i in self { try_visit!(i.visit(visitor, extra)); @@ -1137,18 +1136,11 @@ common_visitor_and_walkers!(Visitor<'a>); macro_rules! generate_list_visit_fns { ($($visit_fn:ident, $ty:ty $(, $extra:ident: $extra_ty:ty)?;)+) => { - $( - #[allow(unused_parens)] - impl<'a, V: Visitor<'a>> Visitable<'a, V> for ThinVec<$ty> { - type Extra = ($($extra_ty)?); - - #[inline] - fn visit(&'a self, visitor: &mut V, ($($extra)?): Self::Extra) -> V::Result { - walk_list!(visitor, $visit_fn, self $(, $extra)?); - V::Result::output() - } - } - )+ + $(impl_visitable!(|&'a self: ThinVec<$ty>, visitor: &mut V, extra: ($($extra_ty)?)| { + let ($($extra)?) = extra; + walk_list!(visitor, $visit_fn, self $(, $extra)?); + V::Result::output() + });)+ } } From d3b4e4cf8967138da99a2300fadfce3a20c8faf8 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 3 Sep 2026 15:53:34 +1000 Subject: [PATCH 06/11] Remove need for `allow(unused_parens)` The AST visitor code uses `($($extra_ty)?)` which expands to `()` in some cases and `(T)` in others, which requires `allow(unused_parens)` to avoid warnings. This commit splits the two `impl_visitable!` macros into two rules: one for the "no-extra" case and one for the "with-extra" case. There's a small amount of duplication between the two rules but there are multiple advantages. - The `allow(unused_parens)` is removed. - `impl_visitable!` callers can omit the extra param if it's `()`. - When the extra argument might or might not be present, a more standard `$(, $extra: $extra_ty)?` is now used. - No weird `let ($($extra)?) = extra;` destructuring. The `Visitable` derive also gets a tweak to avoid unnecessary parens around extra args. --- compiler/rustc_ast/src/mut_visit.rs | 24 ++++++++++------ compiler/rustc_ast/src/visit.rs | 40 +++++++++++++++----------- compiler/rustc_macros/src/visitable.rs | 8 +++--- 3 files changed, 42 insertions(+), 30 deletions(-) diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index de7cf0e9791d4..7ec76eeeb1340 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -156,10 +156,18 @@ macro_rules! visit_visitable_with { } macro_rules! impl_visitable { - (|&mut $self:ident: $self_ty:ty, - $vis:ident: &mut $vis_ty:ident, + // The no-extra case. + (|&mut $self:ident: $self_ty:ty, $vis:ident: &mut $vis_ty:ident| $block:block) => { + impl<$vis_ty: MutVisitor> MutVisitable<$vis_ty> for $self_ty { + type Extra = (); + fn visit_mut(&mut $self, $vis: &mut $vis_ty, _extra: Self::Extra) -> V::Result { + $block + } + } + }; + // The with-extra case. + (|&mut $self:ident: $self_ty:ty, $vis:ident: &mut $vis_ty:ident, $extra:ident: $extra_ty:ty| $block:block) => { - #[allow(unused_parens)] impl<$vis_ty: MutVisitor> MutVisitable<$vis_ty> for $self_ty { type Extra = $extra_ty; fn visit_mut(&mut $self, $vis: &mut $vis_ty, $extra: Self::Extra) -> V::Result { @@ -183,7 +191,7 @@ macro_rules! impl_walkable { macro_rules! impl_visitable_noop { ($($ty:ty,)*) => { $( - impl_visitable!(|&mut self: $ty, _vis: &mut V, _extra: ()| {}); + impl_visitable!(|&mut self: $ty, _vis: &mut V| {}); )* }; } @@ -209,7 +217,7 @@ macro_rules! impl_visitable_list { macro_rules! impl_visitable_direct { ($($ty:ty,)*) => { $(impl_visitable!( - |&mut self: $ty, visitor: &mut V, _extra: ()| { + |&mut self: $ty, visitor: &mut V| { MutWalkable::walk_mut(self, visitor) } );)* @@ -230,8 +238,7 @@ macro_rules! impl_visitable_visit { ($Visitor:ident $( $visit:ident($ty:ty $(, $extra:ident: $extra_ty:ty)?) => $walk:ident; )* ) => { - $(impl_visitable!(|&mut self: $ty, visitor: &mut V, extra: ($($extra_ty)?)| { - let ($($extra)?) = extra; + $(impl_visitable!(|&mut self: $ty, visitor: &mut V $(, $extra: $extra_ty)?| { visitor.$visit(self $(, $extra)?); });)* } @@ -251,8 +258,7 @@ super::common_visitor_and_walkers!((mut) MutVisitor); macro_rules! generate_flat_map_visitor_fns { ($($flat_map_fn:ident, $ty:ty $(, $extra:ident: $extra_ty:ty)?;)+) => { - $(impl_visitable!(|&mut self: ThinVec<$ty>, visitor: &mut V, extra: ($($extra_ty)?)| { - let ($($extra)?) = extra; + $(impl_visitable!(|&mut self: ThinVec<$ty>, visitor: &mut V $(, $extra: $extra_ty)?| { self.flat_map_in_place(|value| visitor.$flat_map_fn(value $(, $extra)?)); });)+ } diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index a2861305a7d24..2632332c0dc62 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -204,10 +204,18 @@ macro_rules! visit_visitable_with { } 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)] + // The no-extra case. + (|&$lt:lifetime $self:ident: $self_ty:ty, $vis:ident: &mut $vis_ty:ident| $block:block) => { + impl<$lt, $vis_ty: Visitor<$lt>> Visitable<$lt, $vis_ty> for $self_ty { + type Extra = (); + fn visit(&$lt $self, $vis: &mut $vis_ty, _extra: Self::Extra) -> V::Result { + $block + } + } + }; + // The with-extra case. + (|&$lt:lifetime $self:ident: $self_ty:ty, $vis:ident: &mut $vis_ty:ident, + $extra:ident: $extra_ty:ty| $block:block) => { 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 { @@ -231,7 +239,7 @@ macro_rules! impl_walkable { macro_rules! impl_visitable_noop { (<$lt:lifetime> $($ty:ty,)*) => { $( - impl_visitable!(|&$lt self: $ty, _vis: &mut V, _extra: ()| { + impl_visitable!(|&$lt self: $ty, _vis: &mut V| { V::Result::output() }); )* @@ -260,7 +268,7 @@ macro_rules! impl_visitable_list { macro_rules! impl_visitable_direct { (<$lt:lifetime> $($ty:ty,)*) => { $(impl_visitable!( - |&$lt self: $ty, visitor: &mut V, _extra: ()| { + |&$lt self: $ty, visitor: &mut V| { Walkable::walk_ref(self, visitor) } );)* @@ -281,8 +289,7 @@ macro_rules! impl_visitable_visit { ($Visitor:ident<$lt:lifetime> $( $visit:ident($ty:ty $(, $extra:ident: $extra_ty:ty)?) => $walk:ident; )* ) => { - $(impl_visitable!(|&$lt self: $ty, visitor: &mut V, extra: ($($extra_ty)?)| { - let ($($extra)?) = extra; + $(impl_visitable!(|&$lt self: $ty, visitor: &mut V $(, $extra: $extra_ty)?| { visitor.$visit(self $(, $extra)?) });)* }; @@ -758,33 +765,33 @@ macro_rules! common_visitor_and_walkers { crate::for_each_ast_visit_hook!($Visitor$(<$lt>)? impl_visitable_visit!); - impl_visitable!(|&$($lt)? $($mut)? self: Ident, visitor: &mut V, _extra: ()| { + impl_visitable!(|&$($lt)? $($mut)? self: Ident, visitor: &mut V| { visitor.visit_ident(self) }); $( impl_visitable!( - |&$lt self: NodeId, visitor: &mut V, _extra: ()| { + |&$lt self: NodeId, visitor: &mut V| { visitor.visit_id(*self) } ); )? $( impl_visitable!( - |&$mut self: NodeId, visitor: &mut V, _extra: ()| { + |&$mut self: NodeId, visitor: &mut V| { visitor.visit_id(self) } ); - impl_visitable!(|&mut self: Span, visitor: &mut V, _extra: ()| { + impl_visitable!(|&mut self: Span, visitor: &mut V| { visitor.visit_span(self) }); )? - impl_visitable!(|&$($lt)? $($mut)? self: Item, vis: &mut V, _extra: ()| { + impl_visitable!(|&$($lt)? $($mut)? self: Item, vis: &mut V| { vis.visit_item(self) }); - impl_visitable!(|&$($lt)? $($mut)? self: ForeignItem, vis: &mut V, _extra: ()| { + impl_visitable!(|&$($lt)? $($mut)? self: ForeignItem, vis: &mut V| { vis.visit_foreign_item(self) }); impl_visitable!(|&$($lt)? $($mut)? self: AssocItem, vis: &mut V, ctxt: AssocCtxt| { @@ -804,7 +811,7 @@ macro_rules! common_visitor_and_walkers { ) -> V::Result; } - $(impl_visitable!(|&$lt self: ThinVec<(UseTree, NodeId)>, vis: &mut V, _extra: ()| { + $(impl_visitable!(|&$lt self: ThinVec<(UseTree, NodeId)>, vis: &mut V| { for (nested_tree, nested_id) in self { try_visit!(vis.visit_nested_use_tree(nested_tree, *nested_id)); } @@ -1136,8 +1143,7 @@ common_visitor_and_walkers!(Visitor<'a>); macro_rules! generate_list_visit_fns { ($($visit_fn:ident, $ty:ty $(, $extra:ident: $extra_ty:ty)?;)+) => { - $(impl_visitable!(|&'a self: ThinVec<$ty>, visitor: &mut V, extra: ($($extra_ty)?)| { - let ($($extra)?) = extra; + $(impl_visitable!(|&'a self: ThinVec<$ty>, visitor: &mut V $(, $extra: $extra_ty)?| { walk_list!(visitor, $visit_fn, self $(, $extra)?); V::Result::output() });)+ diff --git a/compiler/rustc_macros/src/visitable.rs b/compiler/rustc_macros/src/visitable.rs index a7a82538eabe2..ddfc626e599ab 100644 --- a/compiler/rustc_macros/src/visitable.rs +++ b/compiler/rustc_macros/src/visitable.rs @@ -43,21 +43,21 @@ pub(super) fn visitable_derive(mut s: synstructure::Structure<'_>) -> proc_macro s.add_bounds(synstructure::AddBounds::Generics); s.bind_with(|_| synstructure::BindStyle::Ref); let ref_visit = s.each(|bind| { - let extra = get_attr(bind, "extra").unwrap_or(quote! {}); + let extra = get_attr(bind, "extra").unwrap_or(quote! { () }); if has_attr(bind, "ignore") { quote! {} } else { - quote! { rustc_ast_ir::try_visit!(crate::visit::Visitable::visit(#bind, __visitor, (#extra))) } + quote! { rustc_ast_ir::try_visit!(crate::visit::Visitable::visit(#bind, __visitor, #extra)) } } }); s.bind_with(|_| synstructure::BindStyle::RefMut); let mut_visit = s.each(|bind| { - let extra = get_attr(bind, "extra").unwrap_or(quote! {}); + let extra = get_attr(bind, "extra").unwrap_or(quote! { () }); if has_attr(bind, "ignore") { quote! {} } else { - quote! { crate::mut_visit::MutVisitable::visit_mut(#bind, __visitor, (#extra)) } + quote! { crate::mut_visit::MutVisitable::visit_mut(#bind, __visitor, #extra) } } }); From 75fd8533e0d85e66e0bf5f12f4e55dc97840901a Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 3 Sep 2026 17:54:14 +1000 Subject: [PATCH 07/11] Avoid `#[macro_export]` These macros aren't needed outside the crate. --- compiler/rustc_ast/src/mut_visit.rs | 2 +- compiler/rustc_ast/src/visit.rs | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 7ec76eeeb1340..c8975d1009d31 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -254,7 +254,7 @@ macro_rules! fn_walk { }; } -super::common_visitor_and_walkers!((mut) MutVisitor); +crate::visit::common_visitor_and_walkers!((mut) MutVisitor); macro_rules! generate_flat_map_visitor_fns { ($($flat_map_fn:ident, $ty:ty $(, $extra:ident: $extra_ty:ty)?;)+) => { diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 2632332c0dc62..dc9e43bcfac20 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -312,7 +312,6 @@ macro_rules! fn_walk { /// $( $visit:ident($ty:ty $(, $extra:ident: $extra_ty:ty)?) => $walk:ident; )* /// ) => ... /// ``` -#[macro_export] macro_rules! for_each_ast_visit_hook { ($Visitor:ident$(<$lt:lifetime>)? $macro:ident! @@ -382,8 +381,8 @@ macro_rules! for_each_ast_visit_hook { ); }; } +pub(crate) use for_each_ast_visit_hook; -#[macro_export] macro_rules! common_visitor_and_walkers { ($(($mut: ident))? $Visitor:ident$(<$lt:lifetime>)?) => { $(${ignore($lt)} @@ -637,7 +636,7 @@ macro_rules! common_visitor_and_walkers { Self::Result::output() } - crate::for_each_ast_visit_hook!($Visitor$(<$lt>)? fn_visit!); + crate::visit::for_each_ast_visit_hook!($Visitor$(<$lt>)? fn_visit!); // We want `Visitor` to take the `NodeId` by value. fn visit_id(&mut self, _id: $(&$mut)? NodeId) -> Self::Result { @@ -763,7 +762,7 @@ macro_rules! common_visitor_and_walkers { )? } - crate::for_each_ast_visit_hook!($Visitor$(<$lt>)? impl_visitable_visit!); + crate::visit::for_each_ast_visit_hook!($Visitor$(<$lt>)? impl_visitable_visit!); impl_visitable!(|&$($lt)? $($mut)? self: Ident, visitor: &mut V| { visitor.visit_ident(self) @@ -1135,9 +1134,10 @@ macro_rules! common_visitor_and_walkers { V::Result::output() }); - crate::for_each_ast_visit_hook!($Visitor$(<$lt>)? fn_walk!); + crate::visit::for_each_ast_visit_hook!($Visitor$(<$lt>)? fn_walk!); }; } +pub(crate) use common_visitor_and_walkers; common_visitor_and_walkers!(Visitor<'a>); From ad22c2b1ccec033ca217eaab48da858ab85c62dc Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 3 Sep 2026 18:40:20 +1000 Subject: [PATCH 08/11] Don't pass in `$Visitor`/`$lt` to various macros We can just hardwire `'a` and `Visitor`/`MutVisitor`. This simplifies the inputs for these macros from "leading thing + repeating elements" to just "repeating elements". --- compiler/rustc_ast/src/mut_visit.rs | 14 ++---- compiler/rustc_ast/src/visit.rs | 74 +++++++++++++---------------- 2 files changed, 36 insertions(+), 52 deletions(-) diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index c8975d1009d31..a7feb61a9bb40 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -225,9 +225,7 @@ macro_rules! impl_visitable_direct { } macro_rules! fn_visit { - ($Visitor:ident - $( $visit:ident($ty:ty $(, $extra:ident: $extra_ty:ty)?) => $walk:ident; )* - ) => { + ($($visit:ident($ty:ty $(, $extra:ident: $extra_ty:ty)?) => $walk:ident;)*) => { $(fn $visit(&mut self, node: &mut $ty $(, $extra: $extra_ty)?) { MutWalkable::walk_mut(node, self) })* @@ -235,9 +233,7 @@ macro_rules! fn_visit { } macro_rules! impl_visitable_visit { - ($Visitor:ident - $( $visit:ident($ty:ty $(, $extra:ident: $extra_ty:ty)?) => $walk:ident; )* - ) => { + ($($visit:ident($ty:ty $(, $extra:ident: $extra_ty:ty)?) => $walk:ident;)*) => { $(impl_visitable!(|&mut self: $ty, visitor: &mut V $(, $extra: $extra_ty)?| { visitor.$visit(self $(, $extra)?); });)* @@ -245,10 +241,8 @@ macro_rules! impl_visitable_visit { } macro_rules! fn_walk { - ($Visitor:ident - $( $visit:ident($ty:ty $(, $extra:ident: $extra_ty:ty)?) => $walk:ident; )* - ) => { - $(pub fn $walk(visitor: &mut V, node: &mut $ty) { + ($($visit:ident($ty:ty $(, $extra:ident: $extra_ty:ty)?) => $walk:ident;)*) => { + $(pub fn $walk(visitor: &mut V, node: &mut $ty) { MutWalkable::walk_mut(node, visitor) })* }; diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index dc9e43bcfac20..9475be1e9cfe7 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -237,9 +237,9 @@ macro_rules! impl_walkable { } macro_rules! impl_visitable_noop { - (<$lt:lifetime> $($ty:ty,)*) => { + ($($ty:ty,)*) => { $( - impl_visitable!(|&$lt self: $ty, _vis: &mut V| { + impl_visitable!(|&'a self: $ty, _vis: &mut V| { V::Result::output() }); )* @@ -247,15 +247,15 @@ macro_rules! impl_visitable_noop { } macro_rules! impl_visitable_list { - (<$lt:lifetime> $($ty:ty,)*) => { - $(impl<$lt, V: Visitor<$lt>, T> Visitable<$lt, V> for $ty + ($($ty:ty,)*) => { + $(impl<'a, V: Visitor<'a>, T> Visitable<'a, V> for $ty where - &$lt $ty: IntoIterator, - T: $lt + Visitable<$lt, V>, + &'a $ty: IntoIterator, + T: 'a + Visitable<'a, V>, { - type Extra = >::Extra; + type Extra = >::Extra; - fn visit(&$lt self, visitor: &mut V, extra: Self::Extra) -> V::Result { + fn visit(&'a self, visitor: &mut V, extra: Self::Extra) -> V::Result { for i in self { try_visit!(i.visit(visitor, extra)); } @@ -266,9 +266,9 @@ macro_rules! impl_visitable_list { } macro_rules! impl_visitable_direct { - (<$lt:lifetime> $($ty:ty,)*) => { + ($($ty:ty,)*) => { $(impl_visitable!( - |&$lt self: $ty, visitor: &mut V| { + |&'a self: $ty, visitor: &mut V| { Walkable::walk_ref(self, visitor) } );)* @@ -276,30 +276,24 @@ macro_rules! impl_visitable_direct { } macro_rules! fn_visit { - ($Visitor:ident<$lt:lifetime> - $( $visit:ident($ty:ty $(, $extra:ident: $extra_ty:ty)?) => $walk:ident; )* - ) => { - $(fn $visit(&mut self, node: &$lt $ty $(, $extra: $extra_ty)?) -> Self::Result { + ($($visit:ident($ty:ty $(, $extra:ident: $extra_ty:ty)?) => $walk:ident;)*) => { + $(fn $visit(&mut self, node: &'a $ty $(, $extra: $extra_ty)?) -> Self::Result { Walkable::walk_ref(node, self) })* }; } macro_rules! impl_visitable_visit { - ($Visitor:ident<$lt:lifetime> - $( $visit:ident($ty:ty $(, $extra:ident: $extra_ty:ty)?) => $walk:ident; )* - ) => { - $(impl_visitable!(|&$lt self: $ty, visitor: &mut V $(, $extra: $extra_ty)?| { + ($($visit:ident($ty:ty $(, $extra:ident: $extra_ty:ty)?) => $walk:ident;)*) => { + $(impl_visitable!(|&'a self: $ty, visitor: &mut V $(, $extra: $extra_ty)?| { visitor.$visit(self $(, $extra)?) });)* }; } macro_rules! fn_walk { - ($Visitor:ident<$lt:lifetime> - $( $visit:ident($ty:ty $(, $extra:ident: $extra_ty:ty)?) => $walk:ident; )* - ) => { - $(pub fn $walk<$lt, V: $Visitor<$lt>>(visitor: &mut V, node: &$lt $ty) -> V::Result { + ($($visit:ident($ty:ty $(, $extra:ident: $extra_ty:ty)?) => $walk:ident;)*) => { + $(pub fn $walk<'a, V: Visitor<'a>>(visitor: &mut V, node: &'a $ty) -> V::Result { Walkable::walk_ref(node, visitor) })* } @@ -308,15 +302,11 @@ macro_rules! fn_walk { /// Higher-order macro that puts all the visit/walk hook information in a single place. The /// passed-in macro should have a left hand side like this: /// ```ignore (partial) -/// ($Visitor:ident -/// $( $visit:ident($ty:ty $(, $extra:ident: $extra_ty:ty)?) => $walk:ident; )* -/// ) => ... +/// ($($visit:ident($ty:ty $(, $extra:ident: $extra_ty:ty)?) => $walk:ident;)*) => { ... } /// ``` macro_rules! for_each_ast_visit_hook { - ($Visitor:ident$(<$lt:lifetime>)? - $macro:ident! - ) => { - $macro!($Visitor$(<$lt>)? + ($macro:ident!) => { + $macro! { visit_anon_const(AnonConst) => walk_anon_const; visit_arm(Arm) => walk_arm; //visit_assoc_item(AssocItem, _ctxt: AssocCtxt) => walk_assoc_item; @@ -378,13 +368,13 @@ macro_rules! for_each_ast_visit_hook { visit_vis(Visibility) => walk_vis; visit_where_predicate_kind(WherePredicateKind) => walk_where_predicate_kind; visit_where_predicate(WherePredicate) => walk_where_predicate; - ); + } }; } pub(crate) use for_each_ast_visit_hook; macro_rules! common_visitor_and_walkers { - ($(($mut: ident))? $Visitor:ident$(<$lt:lifetime>)?) => { + ($(($mut:ident))? $Visitor:ident$(<$lt:lifetime>)?) => { $(${ignore($lt)} #[derive(Copy, Clone)] )? @@ -433,7 +423,7 @@ macro_rules! common_visitor_and_walkers { } // This macro generates `impl Visitable` and `impl MutVisitable` that do nothing. - impl_visitable_noop!($(<$lt>)? + impl_visitable_noop! { AttrId, bool, rustc_span::ByteSymbol, @@ -455,14 +445,14 @@ macro_rules! common_visitor_and_walkers { SyntheticAttr, u8, usize, - ); - // `Span` is only a no-op for the non-mutable visitor. - $(impl_visitable_noop!(<$lt> Span,);)? + } + // `Span` is a no-op for the immutable visitor. + $(${ignore($lt)} impl_visitable_noop! { 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>)? + impl_visitable_list! { ThinVec, ThinVec, ThinVec, @@ -478,12 +468,12 @@ macro_rules! common_visitor_and_walkers { ThinVec>, ThinVec, ThinVec, - ); + } // 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>)? + impl_visitable_direct! { AngleBracketedArg, AngleBracketedArgs, AsmMacro, @@ -575,7 +565,7 @@ macro_rules! common_visitor_and_walkers { YieldKind, EiiDecl, EiiImpl, - ); + } /// Each method of this trait is a hook to be potentially /// overridden. Each method's default implementation recursively visits @@ -636,7 +626,7 @@ macro_rules! common_visitor_and_walkers { Self::Result::output() } - crate::visit::for_each_ast_visit_hook!($Visitor$(<$lt>)? fn_visit!); + crate::visit::for_each_ast_visit_hook! { fn_visit! } // We want `Visitor` to take the `NodeId` by value. fn visit_id(&mut self, _id: $(&$mut)? NodeId) -> Self::Result { @@ -762,7 +752,7 @@ macro_rules! common_visitor_and_walkers { )? } - crate::visit::for_each_ast_visit_hook!($Visitor$(<$lt>)? impl_visitable_visit!); + crate::visit::for_each_ast_visit_hook! { impl_visitable_visit! } impl_visitable!(|&$($lt)? $($mut)? self: Ident, visitor: &mut V| { visitor.visit_ident(self) @@ -1134,7 +1124,7 @@ macro_rules! common_visitor_and_walkers { V::Result::output() }); - crate::visit::for_each_ast_visit_hook!($Visitor$(<$lt>)? fn_walk!); + crate::visit::for_each_ast_visit_hook! { fn_walk! } }; } pub(crate) use common_visitor_and_walkers; From cd21f63eff3a96740b71ca3e20d965002b9d5aed Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 4 Sep 2026 08:17:20 +1000 Subject: [PATCH 09/11] Use `tidy-alphabetical` markers on various lists A lot of these lists are already almost in alphabetical order. --- compiler/rustc_ast/src/mut_visit.rs | 34 +++++++------ compiler/rustc_ast/src/visit.rs | 78 ++++++++++++++++------------- 2 files changed, 63 insertions(+), 49 deletions(-) diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index a7feb61a9bb40..01bba928a9989 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -259,19 +259,21 @@ macro_rules! generate_flat_map_visitor_fns { } generate_flat_map_visitor_fns! { - flat_map_item, Box; - flat_map_foreign_item, Box; - flat_map_generic_param, GenericParam; - flat_map_stmt, Stmt; + // tidy-alphabetical-start filter_map_expr, Box; // the odd one out; it works because `Option` impls `IntoIterator` + flat_map_arm, Arm; + flat_map_assoc_item, Box, ctxt: AssocCtxt; flat_map_expr_field, ExprField; + flat_map_field_def, FieldDef; + flat_map_foreign_item, Box; + flat_map_generic_param, GenericParam; + flat_map_item, Box; + flat_map_param, Param; flat_map_pat_field, PatField; + flat_map_stmt, Stmt; 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; + // tidy-alphabetical-end } pub fn walk_flat_map_pat_field( @@ -296,16 +298,18 @@ macro_rules! generate_walk_flat_map_fns { } generate_walk_flat_map_fns! { + // tidy-alphabetical-start walk_flat_map_arm(Arm) => visit_arm; - walk_flat_map_variant(Variant) => visit_variant; - walk_flat_map_param(Param) => visit_param; - walk_flat_map_generic_param(GenericParam) => visit_generic_param; - walk_flat_map_where_predicate(WherePredicate) => visit_where_predicate; - walk_flat_map_field_def(FieldDef) => visit_field_def; + walk_flat_map_assoc_item(Box, ctxt: AssocCtxt) => visit_assoc_item; walk_flat_map_expr_field(ExprField) => visit_expr_field; - walk_flat_map_item(Box) => visit_item; + walk_flat_map_field_def(FieldDef) => visit_field_def; walk_flat_map_foreign_item(Box) => visit_foreign_item; - walk_flat_map_assoc_item(Box, ctxt: AssocCtxt) => visit_assoc_item; + walk_flat_map_generic_param(GenericParam) => visit_generic_param; + walk_flat_map_item(Box) => visit_item; + walk_flat_map_param(Param) => visit_param; + walk_flat_map_variant(Variant) => visit_variant; + walk_flat_map_where_predicate(WherePredicate) => visit_where_predicate; + // tidy-alphabetical-end } pub fn walk_filter_map_expr(vis: &mut T, mut e: Box) -> Option> { diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 9475be1e9cfe7..1220472868d4f 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -307,13 +307,13 @@ macro_rules! fn_walk { macro_rules! for_each_ast_visit_hook { ($macro:ident!) => { $macro! { + // tidy-alphabetical-start visit_anon_const(AnonConst) => walk_anon_const; visit_arm(Arm) => walk_arm; //visit_assoc_item(AssocItem, _ctxt: AssocCtxt) => walk_assoc_item; visit_assoc_item_constraint(AssocItemConstraint) => walk_assoc_item_constraint; visit_attribute(Attribute) => walk_attribute; visit_block(Block) => walk_block; - //visit_nested_use_tree((UseTree, NodeId)) => walk_nested_use_tree; visit_capture_by(CaptureBy) => walk_capture_by; visit_closure_binder(ClosureBinder) => walk_closure_binder; visit_contract(FnContract) => walk_contract; @@ -333,9 +333,9 @@ macro_rules! for_each_ast_visit_hook { visit_generic_args(GenericArgs) => walk_generic_args; visit_generic_param(GenericParam) => walk_generic_param; visit_generics(Generics) => walk_generics; + visit_impl_restriction(ImplRestriction) => walk_impl_restriction; visit_inline_asm(InlineAsm) => walk_inline_asm; visit_inline_asm_sym(InlineAsmSym) => walk_inline_asm_sym; - visit_impl_restriction(ImplRestriction) => walk_impl_restriction; //visit_item(Item) => walk_item; visit_label(Label) => walk_label; visit_lifetime(Lifetime, _ctxt: LifetimeCtxt) => walk_lifetime; @@ -343,12 +343,13 @@ macro_rules! for_each_ast_visit_hook { visit_mac_call(MacCall) => walk_mac; visit_macro_def(MacroDef) => walk_macro_def; visit_mut_restriction(MutRestriction) => walk_mut_restriction; - visit_param_bound(GenericBound, _ctxt: BoundKind) => walk_param_bound; + //visit_nested_use_tree((UseTree, NodeId)) => walk_nested_use_tree; visit_param(Param) => walk_param; + visit_param_bound(GenericBound, _ctxt: BoundKind) => walk_param_bound; + visit_pat(Pat) => walk_pat; visit_pat_field(PatField) => walk_pat_field; visit_path(Path) => walk_path; visit_path_segment(PathSegment) => walk_path_segment; - visit_pat(Pat) => walk_pat; visit_poly_trait_ref(PolyTraitRef) => walk_poly_trait_ref; visit_precise_capturing_arg(PreciseCapturingArg) => walk_precise_capturing_arg; visit_qself(QSelf) => walk_qself; @@ -360,14 +361,15 @@ macro_rules! for_each_ast_visit_hook { visit_test_binder_exists(TestBinderExists) => walk_test_binder_exists; visit_test_binder_forall(TestBinderForall) => walk_test_binder_forall; visit_trait_ref(TraitRef) => walk_trait_ref; - visit_ty_pat(TyPat) => walk_ty_pat; visit_ty(Ty) => walk_ty; + visit_ty_pat(TyPat) => walk_ty_pat; visit_use_tree(UseTree) => walk_use_tree; - visit_variant_data(VariantData) => walk_variant_data; visit_variant(Variant) => walk_variant; + visit_variant_data(VariantData) => walk_variant_data; visit_vis(Visibility) => walk_vis; - visit_where_predicate_kind(WherePredicateKind) => walk_where_predicate_kind; visit_where_predicate(WherePredicate) => walk_where_predicate; + visit_where_predicate_kind(WherePredicateKind) => walk_where_predicate_kind; + // tidy-alphabetical-end } }; } @@ -424,9 +426,15 @@ macro_rules! common_visitor_and_walkers { // This macro generates `impl Visitable` and `impl MutVisitable` that do nothing. impl_visitable_noop! { + // tidy-alphabetical-start AttrId, + Movability, + Mutability, + Pinnedness, + Result<(), rustc_span::ErrorGuaranteed>, + Symbol, + SyntheticAttr, bool, - rustc_span::ByteSymbol, char, crate::token::CommentKind, crate::token::Delimiter, @@ -434,17 +442,13 @@ macro_rules! common_visitor_and_walkers { crate::token::LitKind, crate::tokenstream::LazyAttrTokenStream, crate::tokenstream::TokenStream, - Movability, - Mutability, - Pinnedness, - Result<(), rustc_span::ErrorGuaranteed>, rustc_data_structures::fx::FxHashMap, + rustc_span::ByteSymbol, rustc_span::ErrorGuaranteed, std::borrow::Cow<'_, str>, - Symbol, - SyntheticAttr, u8, usize, + // tidy-alphabetical-end } // `Span` is a no-op for the immutable visitor. $(${ignore($lt)} impl_visitable_noop! { Span, })? @@ -453,27 +457,30 @@ macro_rules! common_visitor_and_walkers { // their contents. We do not use a generic impl for `ThinVec` because we want to allow // custom visits for the `MutVisitor`. impl_visitable_list! { + // tidy-alphabetical-start + ThinVec<(Ident, Option)>, + ThinVec<(NodeId, Path)>, ThinVec, ThinVec, + ThinVec>, + ThinVec, ThinVec, ThinVec, - ThinVec<(Ident, Option)>, - ThinVec<(NodeId, Path)>, + ThinVec, ThinVec, ThinVec, - ThinVec, ThinVec, ThinVec, ThinVec, - ThinVec>, ThinVec, - ThinVec, + // tidy-alphabetical-end } // 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! { + // tidy-alphabetical-start AngleBracketedArg, AngleBracketedArgs, AsmMacro, @@ -483,12 +490,8 @@ macro_rules! common_visitor_and_walkers { AttrItem, AttrKind, AttrStyle, - FnPtrTy, - BindingMode, - CoroutineKind, - RangeLimits, - UnsafeBinderCastKind, BinOpKind, + BindingMode, BlockCheckMode, BorrowKind, BoundAsyncness, @@ -499,14 +502,18 @@ macro_rules! common_visitor_and_walkers { Const, ConstBlockItem, ConstItem, + CoroutineKind, Defaultness, Delegation, DelegationMac, DelegationSuffixes, DelimArgs, DelimSpan, + EiiDecl, + EiiImpl, EnumDef, Extern, + FnPtrTy, ForLoopKind, FormatArgPosition, FormatArgsPiece, @@ -537,6 +544,7 @@ macro_rules! common_visitor_and_walkers { PatFieldsRest, PatKind, RangeEnd, + RangeLimits, RangeSyntax, Recovered, RestrictionKind, @@ -554,6 +562,7 @@ macro_rules! common_visitor_and_walkers { TyKind, TyPatKind, UnOp, + UnsafeBinderCastKind, UnsafeBinderTy, UnsafeSource, UseTreeKind, @@ -563,8 +572,7 @@ macro_rules! common_visitor_and_walkers { WhereEqPredicate, WhereRegionPredicate, YieldKind, - EiiDecl, - EiiImpl, + // tidy-alphabetical-end } /// Each method of this trait is a hook to be potentially @@ -1141,19 +1149,21 @@ macro_rules! generate_list_visit_fns { } generate_list_visit_fns! { - visit_item, Box; - visit_foreign_item, Box; - visit_generic_param, GenericParam; - visit_stmt, Stmt; + // tidy-alphabetical-start + visit_arm, Arm; + visit_assoc_item, Box, ctxt: AssocCtxt; visit_expr, Box; visit_expr_field, ExprField; + visit_field_def, FieldDef; + visit_foreign_item, Box; + visit_generic_param, GenericParam; + visit_item, Box; + visit_param, Param; visit_pat_field, PatField; + visit_stmt, Stmt; visit_variant, Variant; - visit_assoc_item, Box, ctxt: AssocCtxt; visit_where_predicate, WherePredicate; - visit_param, Param; - visit_field_def, FieldDef; - visit_arm, Arm; + // tidy-alphabetical-end } pub fn walk_stmt<'a, V: Visitor<'a>>(visitor: &mut V, statement: &'a Stmt) -> V::Result { From 712e3221f53f645af1eafaf9d7cb3de343941e43 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 7 Sep 2026 09:28:23 +1000 Subject: [PATCH 10/11] Inline `visit`/`visit_mut` in `impl_visitable` --- compiler/rustc_ast/src/mut_visit.rs | 5 +++++ compiler/rustc_ast/src/visit.rs | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 01bba928a9989..ad03222b4d261 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -160,6 +160,8 @@ macro_rules! impl_visitable { (|&mut $self:ident: $self_ty:ty, $vis:ident: &mut $vis_ty:ident| $block:block) => { impl<$vis_ty: MutVisitor> MutVisitable<$vis_ty> for $self_ty { type Extra = (); + + #[inline] fn visit_mut(&mut $self, $vis: &mut $vis_ty, _extra: Self::Extra) -> V::Result { $block } @@ -170,6 +172,8 @@ macro_rules! impl_visitable { $extra:ident: $extra_ty:ty| $block:block) => { impl<$vis_ty: MutVisitor> MutVisitable<$vis_ty> for $self_ty { type Extra = $extra_ty; + + #[inline] fn visit_mut(&mut $self, $vis: &mut $vis_ty, $extra: Self::Extra) -> V::Result { $block } @@ -205,6 +209,7 @@ macro_rules! impl_visitable_list { { type Extra = >::Extra; + #[inline] fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra) { for i in self { i.visit_mut(visitor, extra); diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 1220472868d4f..a9aef493bddf0 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -208,6 +208,8 @@ macro_rules! impl_visitable { (|&$lt:lifetime $self:ident: $self_ty:ty, $vis:ident: &mut $vis_ty:ident| $block:block) => { impl<$lt, $vis_ty: Visitor<$lt>> Visitable<$lt, $vis_ty> for $self_ty { type Extra = (); + + #[inline] fn visit(&$lt $self, $vis: &mut $vis_ty, _extra: Self::Extra) -> V::Result { $block } @@ -218,6 +220,8 @@ macro_rules! impl_visitable { $extra:ident: $extra_ty:ty| $block:block) => { impl<$lt, $vis_ty: Visitor<$lt>> Visitable<$lt, $vis_ty> for $self_ty { type Extra = $extra_ty; + + #[inline] fn visit(&$lt $self, $vis: &mut $vis_ty, $extra: Self::Extra) -> V::Result { $block } From 44aee3970788cb7fa255f5584aef0ceb151449d2 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 14 Sep 2026 08:00:20 +1000 Subject: [PATCH 11/11] Rename `ty` macro parameters As requested by the reviewer. --- compiler/rustc_ast/src/mut_visit.rs | 54 ++++++++++++++--------------- compiler/rustc_ast/src/visit.rs | 48 ++++++++++++------------- 2 files changed, 51 insertions(+), 51 deletions(-) diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index ad03222b4d261..f1cf8a912b58a 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -157,8 +157,8 @@ macro_rules! visit_visitable_with { macro_rules! impl_visitable { // The no-extra case. - (|&mut $self:ident: $self_ty:ty, $vis:ident: &mut $vis_ty:ident| $block:block) => { - impl<$vis_ty: MutVisitor> MutVisitable<$vis_ty> for $self_ty { + (|&mut $self:ident: $SelfTy:ty, $vis:ident: &mut $vis_ty:ident| $block:block) => { + impl<$vis_ty: MutVisitor> MutVisitable<$vis_ty> for $SelfTy { type Extra = (); #[inline] @@ -168,10 +168,10 @@ macro_rules! impl_visitable { } }; // The with-extra case. - (|&mut $self:ident: $self_ty:ty, $vis:ident: &mut $vis_ty:ident, - $extra:ident: $extra_ty:ty| $block:block) => { - impl<$vis_ty: MutVisitor> MutVisitable<$vis_ty> for $self_ty { - type Extra = $extra_ty; + (|&mut $self:ident: $SelfTy:ty, $vis:ident: &mut $vis_ty:ident, + $extra:ident: $ExtraTy:ty| $block:block) => { + impl<$vis_ty: MutVisitor> MutVisitable<$vis_ty> for $SelfTy { + type Extra = $ExtraTy; #[inline] fn visit_mut(&mut $self, $vis: &mut $vis_ty, $extra: Self::Extra) -> V::Result { @@ -182,9 +182,9 @@ macro_rules! impl_visitable { } macro_rules! impl_walkable { - (|&mut $self:ident: $self_ty:ty, + (|&mut $self:ident: $SelfTy:ty, $vis:ident: &mut $vis_ty:ident| $block:block) => { - impl<$vis_ty: MutVisitor> MutWalkable<$vis_ty> for $self_ty { + impl<$vis_ty: MutVisitor> MutWalkable<$vis_ty> for $SelfTy { fn walk_mut(&mut $self, $vis: &mut $vis_ty) -> V::Result { $block } @@ -193,18 +193,18 @@ macro_rules! impl_walkable { } macro_rules! impl_visitable_noop { - ($($ty:ty,)*) => { + ($($Ty:ty,)*) => { $( - impl_visitable!(|&mut self: $ty, _vis: &mut V| {}); + impl_visitable!(|&mut self: $Ty, _vis: &mut V| {}); )* }; } macro_rules! impl_visitable_list { - ($($ty:ty,)*) => { - $(impl MutVisitable for $ty + ($($Ty:ty,)*) => { + $(impl MutVisitable for $Ty where - for<'a> &'a mut $ty: IntoIterator, + for<'a> &'a mut $Ty: IntoIterator, T: MutVisitable, { type Extra = >::Extra; @@ -220,9 +220,9 @@ macro_rules! impl_visitable_list { } macro_rules! impl_visitable_direct { - ($($ty:ty,)*) => { + ($($Ty:ty,)*) => { $(impl_visitable!( - |&mut self: $ty, visitor: &mut V| { + |&mut self: $Ty, visitor: &mut V| { MutWalkable::walk_mut(self, visitor) } );)* @@ -230,24 +230,24 @@ macro_rules! impl_visitable_direct { } macro_rules! fn_visit { - ($($visit:ident($ty:ty $(, $extra:ident: $extra_ty:ty)?) => $walk:ident;)*) => { - $(fn $visit(&mut self, node: &mut $ty $(, $extra: $extra_ty)?) { + ($($visit:ident($Ty:ty $(, $extra:ident: $ExtraTy:ty)?) => $walk:ident;)*) => { + $(fn $visit(&mut self, node: &mut $Ty $(, $extra: $ExtraTy)?) { MutWalkable::walk_mut(node, self) })* } } macro_rules! impl_visitable_visit { - ($($visit:ident($ty:ty $(, $extra:ident: $extra_ty:ty)?) => $walk:ident;)*) => { - $(impl_visitable!(|&mut self: $ty, visitor: &mut V $(, $extra: $extra_ty)?| { + ($($visit:ident($Ty:ty $(, $extra:ident: $ExtraTy:ty)?) => $walk:ident;)*) => { + $(impl_visitable!(|&mut self: $Ty, visitor: &mut V $(, $extra: $ExtraTy)?| { visitor.$visit(self $(, $extra)?); });)* } } macro_rules! fn_walk { - ($($visit:ident($ty:ty $(, $extra:ident: $extra_ty:ty)?) => $walk:ident;)*) => { - $(pub fn $walk(visitor: &mut V, node: &mut $ty) { + ($($visit:ident($Ty:ty $(, $extra:ident: $ExtraTy:ty)?) => $walk:ident;)*) => { + $(pub fn $walk(visitor: &mut V, node: &mut $Ty) { MutWalkable::walk_mut(node, visitor) })* }; @@ -256,8 +256,8 @@ macro_rules! fn_walk { crate::visit::common_visitor_and_walkers!((mut) MutVisitor); macro_rules! generate_flat_map_visitor_fns { - ($($flat_map_fn:ident, $ty:ty $(, $extra:ident: $extra_ty:ty)?;)+) => { - $(impl_visitable!(|&mut self: ThinVec<$ty>, visitor: &mut V $(, $extra: $extra_ty)?| { + ($($flat_map_fn:ident, $Ty:ty $(, $extra:ident: $ExtraTy:ty)?;)+) => { + $(impl_visitable!(|&mut self: ThinVec<$Ty>, visitor: &mut V $(, $extra: $ExtraTy)?| { self.flat_map_in_place(|value| visitor.$flat_map_fn(value $(, $extra)?)); });)+ } @@ -290,12 +290,12 @@ pub fn walk_flat_map_pat_field( } macro_rules! generate_walk_flat_map_fns { - ($($fn_name:ident($ty:ty $(, $extra:ident: $extra_ty:ty)?) => $visit_fn_name:ident;)+) => {$( + ($($fn_name:ident($Ty:ty $(, $extra:ident: $ExtraTy:ty)?) => $visit_fn_name:ident;)+) => {$( pub fn $fn_name( vis: &mut V, - mut value: $ty - $(, $extra: $extra_ty)? - ) -> SmallVec<[$ty; 1]> { + mut value: $Ty + $(, $extra: $ExtraTy)? + ) -> SmallVec<[$Ty; 1]> { vis.$visit_fn_name(&mut value$(, $extra)*); smallvec![value] } diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index a9aef493bddf0..c12f24a7eff87 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -205,8 +205,8 @@ macro_rules! visit_visitable_with { macro_rules! impl_visitable { // The no-extra case. - (|&$lt:lifetime $self:ident: $self_ty:ty, $vis:ident: &mut $vis_ty:ident| $block:block) => { - impl<$lt, $vis_ty: Visitor<$lt>> Visitable<$lt, $vis_ty> for $self_ty { + (|&$lt:lifetime $self:ident: $SelfTy:ty, $vis:ident: &mut $vis_ty:ident| $block:block) => { + impl<$lt, $vis_ty: Visitor<$lt>> Visitable<$lt, $vis_ty> for $SelfTy { type Extra = (); #[inline] @@ -216,10 +216,10 @@ macro_rules! impl_visitable { } }; // The with-extra case. - (|&$lt:lifetime $self:ident: $self_ty:ty, $vis:ident: &mut $vis_ty:ident, - $extra:ident: $extra_ty:ty| $block:block) => { - impl<$lt, $vis_ty: Visitor<$lt>> Visitable<$lt, $vis_ty> for $self_ty { - type Extra = $extra_ty; + (|&$lt:lifetime $self:ident: $SelfTy:ty, $vis:ident: &mut $vis_ty:ident, + $extra:ident: $ExtraTy:ty| $block:block) => { + impl<$lt, $vis_ty: Visitor<$lt>> Visitable<$lt, $vis_ty> for $SelfTy { + type Extra = $ExtraTy; #[inline] fn visit(&$lt $self, $vis: &mut $vis_ty, $extra: Self::Extra) -> V::Result { @@ -230,9 +230,9 @@ macro_rules! impl_visitable { } macro_rules! impl_walkable { - (|&$lt:lifetime $self:ident: $self_ty:ty, + (|&$lt:lifetime $self:ident: $SelfTy:ty, $vis:ident: &mut $vis_ty:ident| $block:block) => { - impl<$lt, $vis_ty: Visitor<$lt>> Walkable<$lt, $vis_ty> for $self_ty { + impl<$lt, $vis_ty: Visitor<$lt>> Walkable<$lt, $vis_ty> for $SelfTy { fn walk_ref(&$lt $self, $vis: &mut $vis_ty) -> V::Result { $block } @@ -241,9 +241,9 @@ macro_rules! impl_walkable { } macro_rules! impl_visitable_noop { - ($($ty:ty,)*) => { + ($($Ty:ty,)*) => { $( - impl_visitable!(|&'a self: $ty, _vis: &mut V| { + impl_visitable!(|&'a self: $Ty, _vis: &mut V| { V::Result::output() }); )* @@ -251,10 +251,10 @@ macro_rules! impl_visitable_noop { } macro_rules! impl_visitable_list { - ($($ty:ty,)*) => { - $(impl<'a, V: Visitor<'a>, T> Visitable<'a, V> for $ty + ($($Ty:ty,)*) => { + $(impl<'a, V: Visitor<'a>, T> Visitable<'a, V> for $Ty where - &'a $ty: IntoIterator, + &'a $Ty: IntoIterator, T: 'a + Visitable<'a, V>, { type Extra = >::Extra; @@ -270,9 +270,9 @@ macro_rules! impl_visitable_list { } macro_rules! impl_visitable_direct { - ($($ty:ty,)*) => { + ($($Ty:ty,)*) => { $(impl_visitable!( - |&'a self: $ty, visitor: &mut V| { + |&'a self: $Ty, visitor: &mut V| { Walkable::walk_ref(self, visitor) } );)* @@ -280,24 +280,24 @@ macro_rules! impl_visitable_direct { } macro_rules! fn_visit { - ($($visit:ident($ty:ty $(, $extra:ident: $extra_ty:ty)?) => $walk:ident;)*) => { - $(fn $visit(&mut self, node: &'a $ty $(, $extra: $extra_ty)?) -> Self::Result { + ($($visit:ident($Ty:ty $(, $extra:ident: $ExtraTy:ty)?) => $walk:ident;)*) => { + $(fn $visit(&mut self, node: &'a $Ty $(, $extra: $ExtraTy)?) -> Self::Result { Walkable::walk_ref(node, self) })* }; } macro_rules! impl_visitable_visit { - ($($visit:ident($ty:ty $(, $extra:ident: $extra_ty:ty)?) => $walk:ident;)*) => { - $(impl_visitable!(|&'a self: $ty, visitor: &mut V $(, $extra: $extra_ty)?| { + ($($visit:ident($Ty:ty $(, $extra:ident: $ExtraTy:ty)?) => $walk:ident;)*) => { + $(impl_visitable!(|&'a self: $Ty, visitor: &mut V $(, $extra: $ExtraTy)?| { visitor.$visit(self $(, $extra)?) });)* }; } macro_rules! fn_walk { - ($($visit:ident($ty:ty $(, $extra:ident: $extra_ty:ty)?) => $walk:ident;)*) => { - $(pub fn $walk<'a, V: Visitor<'a>>(visitor: &mut V, node: &'a $ty) -> V::Result { + ($($visit:ident($Ty:ty $(, $extra:ident: $ExtraTy:ty)?) => $walk:ident;)*) => { + $(pub fn $walk<'a, V: Visitor<'a>>(visitor: &mut V, node: &'a $Ty) -> V::Result { Walkable::walk_ref(node, visitor) })* } @@ -306,7 +306,7 @@ macro_rules! fn_walk { /// Higher-order macro that puts all the visit/walk hook information in a single place. The /// passed-in macro should have a left hand side like this: /// ```ignore (partial) -/// ($($visit:ident($ty:ty $(, $extra:ident: $extra_ty:ty)?) => $walk:ident;)*) => { ... } +/// ($($visit:ident($Ty:ty $(, $extra:ident: $ExtraTy:ty)?) => $walk:ident;)*) => { ... } /// ``` macro_rules! for_each_ast_visit_hook { ($macro:ident!) => { @@ -1144,8 +1144,8 @@ pub(crate) use common_visitor_and_walkers; common_visitor_and_walkers!(Visitor<'a>); macro_rules! generate_list_visit_fns { - ($($visit_fn:ident, $ty:ty $(, $extra:ident: $extra_ty:ty)?;)+) => { - $(impl_visitable!(|&'a self: ThinVec<$ty>, visitor: &mut V $(, $extra: $extra_ty)?| { + ($($visit_fn:ident, $Ty:ty $(, $extra:ident: $ExtraTy:ty)?;)+) => { + $(impl_visitable!(|&'a self: ThinVec<$Ty>, visitor: &mut V $(, $extra: $ExtraTy)?| { walk_list!(visitor, $visit_fn, self $(, $extra)?); V::Result::output() });)+