From 568c6ed8c97e398aff6d17c3fe6492dfc1256d33 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Sun, 9 Nov 2025 13:26:40 +0100 Subject: [PATCH] propagate function attributes in ast visitor --- compiler/rustc_ast/src/visit.rs | 17 +++++++++++------ compiler/rustc_ast_passes/src/ast_validation.rs | 6 +++--- compiler/rustc_ast_passes/src/feature_gate.rs | 5 ++--- compiler/rustc_lint/src/early.rs | 4 ++-- compiler/rustc_passes/src/input_stats.rs | 4 ++-- .../rustc_resolve/src/build_reduced_graph.rs | 2 +- compiler/rustc_resolve/src/def_collector.rs | 2 +- compiler/rustc_resolve/src/late.rs | 2 +- 8 files changed, 23 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 4ae193a42ff2..094875f38d74 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -645,8 +645,9 @@ macro_rules! common_visitor_and_walkers { fn visit_fn( &mut self, fk: FnKind<$($lt)? $(${ignore($mut)} '_)?>, + _: &AttrVec, _: Span, - _: NodeId + _: NodeId, ) -> Self::Result { walk_fn(self, fk) } @@ -740,6 +741,7 @@ macro_rules! common_visitor_and_walkers { type Ctxt; fn walk<$($lt,)? V: $Visitor$(<$lt>)?>( &$($lt)? $($mut)? self, + attrs: &AttrVec, span: Span, id: NodeId, visibility: &$($lt)? $($mut)? Visibility, @@ -773,7 +775,7 @@ macro_rules! common_visitor_and_walkers { ) -> V::Result { let Item { attrs, id, kind, vis, span, tokens: _ } = item; visit_visitable!($($mut)? visitor, id, attrs, vis); - try_visit!(kind.walk(*span, *id, vis, ctxt, visitor)); + try_visit!(kind.walk(attrs, *span, *id, vis, ctxt, visitor)); visit_visitable!($($mut)? visitor, span); V::Result::output() } @@ -799,6 +801,7 @@ macro_rules! common_visitor_and_walkers { type Ctxt = (); fn walk<$($lt,)? V: $Visitor$(<$lt>)?>( &$($lt)? $($mut)? self, + attrs: &AttrVec, span: Span, id: NodeId, visibility: &$($lt)? $($mut)? Visibility, @@ -808,7 +811,7 @@ macro_rules! common_visitor_and_walkers { match self { ItemKind::Fn(func) => { let kind = FnKind::Fn(FnCtxt::Free, visibility, &$($mut)? *func); - try_visit!(vis.visit_fn(kind, span, id)); + try_visit!(vis.visit_fn(kind, attrs, span, id)); } ItemKind::ExternCrate(orig_name, ident) => visit_visitable!($($mut)? vis, orig_name, ident), @@ -856,6 +859,7 @@ macro_rules! common_visitor_and_walkers { type Ctxt = AssocCtxt; fn walk<$($lt,)? V: $Visitor$(<$lt>)?>( &$($lt)? $($mut)? self, + attrs: &AttrVec, span: Span, id: NodeId, visibility: &$($lt)? $($mut)? Visibility, @@ -867,7 +871,7 @@ macro_rules! common_visitor_and_walkers { visit_visitable!($($mut)? vis, item), AssocItemKind::Fn(func) => { let kind = FnKind::Fn(FnCtxt::Assoc(ctxt), visibility, &$($mut)? *func); - try_visit!(vis.visit_fn(kind, span, id)) + try_visit!(vis.visit_fn(kind, attrs, span, id)) } AssocItemKind::Type(alias) => visit_visitable!($($mut)? vis, alias), @@ -886,6 +890,7 @@ macro_rules! common_visitor_and_walkers { type Ctxt = (); fn walk<$($lt,)? V: $Visitor$(<$lt>)?>( &$($lt)? $($mut)? self, + attrs: &AttrVec, span: Span, id: NodeId, visibility: &$($lt)? $($mut)? Visibility, @@ -897,7 +902,7 @@ macro_rules! common_visitor_and_walkers { visit_visitable!($($mut)? vis, item), ForeignItemKind::Fn(func) => { let kind = FnKind::Fn(FnCtxt::Foreign, visibility, &$($mut)?*func); - try_visit!(vis.visit_fn(kind, span, id)) + try_visit!(vis.visit_fn(kind, attrs, span, id)) } ForeignItemKind::TyAlias(alias) => visit_visitable!($($mut)? vis, alias), @@ -999,7 +1004,7 @@ macro_rules! common_visitor_and_walkers { }) => { visit_visitable!($($mut)? vis, constness, movability, capture_clause); let kind = FnKind::Closure(binder, coroutine_kind, fn_decl, body); - try_visit!(vis.visit_fn(kind, *span, *id)); + try_visit!(vis.visit_fn(kind, attrs, *span, *id)); visit_visitable!($($mut)? vis, fn_decl_span, fn_arg_span); } ExprKind::Block(block, opt_label) => diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 7a79accc66c2..e7d066ea97cb 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -1104,7 +1104,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } let kind = FnKind::Fn(FnCtxt::Free, &item.vis, &*func); - self.visit_fn(kind, item.span, item.id); + self.visit_fn(kind, &item.attrs, item.span, item.id); } ItemKind::ForeignMod(ForeignMod { extern_span, abi, safety, .. }) => { let old_item = mem::replace(&mut self.extern_mod_span, Some(item.span)); @@ -1478,7 +1478,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { visit::walk_param_bound(self, bound) } - fn visit_fn(&mut self, fk: FnKind<'a>, span: Span, id: NodeId) { + fn visit_fn(&mut self, fk: FnKind<'a>, _attrs: &AttrVec, span: Span, id: NodeId) { // Only associated `fn`s can have `self` parameters. let self_semantic = match fk.ctxt() { Some(FnCtxt::Assoc(_)) => SelfSemantic::Yes, @@ -1648,7 +1648,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { { self.visit_attrs_vis_ident(&item.attrs, &item.vis, &func.ident); let kind = FnKind::Fn(FnCtxt::Assoc(ctxt), &item.vis, &*func); - self.visit_fn(kind, item.span, item.id); + self.visit_fn(kind, &item.attrs, item.span, item.id); } AssocItemKind::Type(_) => { let disallowed = (!parent_is_const).then(|| match self.outer_trait_or_trait_impl { diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index b8a29a9a08f4..2d87d8c84d7c 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -1,6 +1,5 @@ -use rustc_ast as ast; use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor}; -use rustc_ast::{NodeId, PatKind, attr, token}; +use rustc_ast::{self as ast, AttrVec, NodeId, PatKind, attr, token}; use rustc_feature::{AttributeGate, BUILTIN_ATTRIBUTE_MAP, BuiltinAttribute, Features}; use rustc_session::Session; use rustc_session::parse::{feature_err, feature_warn}; @@ -392,7 +391,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { visit::walk_poly_trait_ref(self, t); } - fn visit_fn(&mut self, fn_kind: FnKind<'a>, span: Span, _: NodeId) { + fn visit_fn(&mut self, fn_kind: FnKind<'a>, _: &AttrVec, span: Span, _: NodeId) { if let Some(_header) = fn_kind.header() { // Stability of const fn methods are covered in `visit_assoc_item` below. } diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs index dff1fc436702..6cb5aea79840 100644 --- a/compiler/rustc_lint/src/early.rs +++ b/compiler/rustc_lint/src/early.rs @@ -5,7 +5,7 @@ //! syntactical lints. use rustc_ast::visit::{self as ast_visit, Visitor, walk_list}; -use rustc_ast::{self as ast, HasAttrs}; +use rustc_ast::{self as ast, AttrVec, HasAttrs}; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_errors::{BufferedEarlyLint, DecorateDiagCompat, LintBuffer}; use rustc_feature::Features; @@ -135,7 +135,7 @@ impl<'ast, 'ecx, 'tcx, T: EarlyLintPass> ast_visit::Visitor<'ast> }); } - fn visit_fn(&mut self, fk: ast_visit::FnKind<'ast>, span: Span, id: ast::NodeId) { + fn visit_fn(&mut self, fk: ast_visit::FnKind<'ast>, _: &AttrVec, span: Span, id: ast::NodeId) { lint_callback!(self, check_fn, fk, span, id); ast_visit::walk_fn(self, fk); } diff --git a/compiler/rustc_passes/src/input_stats.rs b/compiler/rustc_passes/src/input_stats.rs index c83610da1aad..fe50b730256b 100644 --- a/compiler/rustc_passes/src/input_stats.rs +++ b/compiler/rustc_passes/src/input_stats.rs @@ -3,7 +3,7 @@ // completely accurate (some things might be counted twice, others missed). use rustc_ast::visit::BoundKind; -use rustc_ast::{self as ast, NodeId, visit as ast_visit}; +use rustc_ast::{self as ast, AttrVec, NodeId, visit as ast_visit}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::thousands::usize_with_underscores; use rustc_hir::{self as hir, AmbigArg, HirId, intravisit as hir_visit}; @@ -709,7 +709,7 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> { ast_visit::walk_where_predicate(self, p) } - fn visit_fn(&mut self, fk: ast_visit::FnKind<'v>, _: Span, _: NodeId) { + fn visit_fn(&mut self, fk: ast_visit::FnKind<'v>, _: &AttrVec, _: Span, _: NodeId) { self.record("FnDecl", None, fk.decl()); ast_visit::walk_fn(self, fk) } diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 886ffcffbb4d..cd12d5ad10cf 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -1358,7 +1358,7 @@ impl<'a, 'ra, 'tcx> Visitor<'a> for BuildReducedGraphVisitor<'a, 'ra, 'tcx> { // Visit attributes after items for backward compatibility. // This way they can use `macro_rules` defined later. self.visit_vis(&item.vis); - item.kind.walk(item.span, item.id, &item.vis, (), self); + item.kind.walk(&item.attrs, item.span, item.id, &item.vis, (), self); visit::walk_list!(self, visit_attribute, &item.attrs); } _ => visit::walk_item(self, item), diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index 14538df8187d..ea64a1e6c64d 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -193,7 +193,7 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { }); } - fn visit_fn(&mut self, fn_kind: FnKind<'a>, span: Span, _: NodeId) { + fn visit_fn(&mut self, fn_kind: FnKind<'a>, _: &AttrVec, span: Span, _: NodeId) { match fn_kind { FnKind::Fn( _ctxt, diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 16cbfe3b3c74..107803c5c265 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -1034,7 +1034,7 @@ impl<'ast, 'ra, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'ra, 'tc } } } - fn visit_fn(&mut self, fn_kind: FnKind<'ast>, sp: Span, fn_id: NodeId) { + fn visit_fn(&mut self, fn_kind: FnKind<'ast>, _: &AttrVec, sp: Span, fn_id: NodeId) { let previous_value = self.diag_metadata.current_function; match fn_kind { // Bail if the function is foreign, and thus cannot validly have