From 607a0c1c2973b1e2b562ec41e7c61b66ab6ca5eb Mon Sep 17 00:00:00 2001 From: Emmanuel Ugwu Date: Sun, 14 Jun 2026 18:46:12 +0100 Subject: [PATCH 1/2] filter out derive helper attributes during ast lowering but keeping them for rustdoc --- compiler/rustc_attr_parsing/src/interface.rs | 21 ++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/interface.rs b/compiler/rustc_attr_parsing/src/interface.rs index e8bef70be550a..de2143ba50ece 100644 --- a/compiler/rustc_attr_parsing/src/interface.rs +++ b/compiler/rustc_attr_parsing/src/interface.rs @@ -292,6 +292,11 @@ impl<'sess> AttributeParser<'sess> { mut emit_lint: impl FnMut(LintId, MultiSpan, EmitAttribute), ) -> Vec { let mut attributes = Vec::new(); + // We store the attributes we intend to discard at the end of this function in order to + // check they are applied to the right target and error out if necessary. In practice, we + // end up dropping only derive attributes and derive helpers, both being fully processed + // at macro expansion. + let mut dropped_attributes = Vec::new(); let mut attr_paths: Vec> = Vec::new(); let mut early_parsed_state = EarlyParsedState::default(); @@ -452,7 +457,19 @@ impl<'sess> AttributeParser<'sess> { self.check_invalid_crate_level_attr_item(&attr, inner_span); } - attributes.push(Attribute::Unparsed(Box::new(attr))); + let attr = Attribute::Unparsed(Box::new(attr)); + + if self.sess.opts.actually_rustdoc + || self.tools.is_some_and(|t| t.iter().any(|i| i.name == parts[0])) + // FIXME: this can be removed once #152369 has been merged. + // https://github.com/rust-lang/rust/pull/152369 + || [sym::allow, sym::deny, sym::expect, sym::forbid, sym::warn] + .contains(&parts[0]) + { + attributes.push(attr); + } else { + dropped_attributes.push(attr); + } }; } } @@ -476,7 +493,7 @@ impl<'sess> AttributeParser<'sess> { } if !matches!(self.should_emit, ShouldEmit::Nothing) && target == Target::WherePredicate { - self.check_invalid_where_predicate_attrs(attributes.iter()); + self.check_invalid_where_predicate_attrs(attributes.iter().chain(&dropped_attributes)); } attributes From 74a384c15db7e198868d44bbeed5f9b8dc90c133 Mon Sep 17 00:00:00 2001 From: Emmanuel Ugwu Date: Mon, 15 Jun 2026 08:27:03 +0100 Subject: [PATCH 2/2] edit comment so it up to date with PR link --- compiler/rustc_attr_parsing/src/interface.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/interface.rs b/compiler/rustc_attr_parsing/src/interface.rs index de2143ba50ece..662e5197d88d1 100644 --- a/compiler/rustc_attr_parsing/src/interface.rs +++ b/compiler/rustc_attr_parsing/src/interface.rs @@ -461,8 +461,8 @@ impl<'sess> AttributeParser<'sess> { if self.sess.opts.actually_rustdoc || self.tools.is_some_and(|t| t.iter().any(|i| i.name == parts[0])) - // FIXME: this can be removed once #152369 has been merged. - // https://github.com/rust-lang/rust/pull/152369 + // FIXME: this can be removed once #155691 has been merged. + // https://github.com/rust-lang/rust/pull/155691 || [sym::allow, sym::deny, sym::expect, sym::forbid, sym::warn] .contains(&parts[0]) {