about summary refs log tree commit diff
path: root/compiler/rustc_attr_parsing/src/attributes
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2025-07-02 23:29:03 +0000
committerbors <bors@rust-lang.org>2025-07-02 23:29:03 +0000
commit25face9808491588e59b6d7844f2185b09eef479 (patch)
treeabcc3b9fad3d64a7be4fb2dc6f93293f5a39308b /compiler/rustc_attr_parsing/src/attributes
parent6677875279b560442a07a08d5119b4cd6b3c5593 (diff)
parentbc8bcc7e8a9d4caf6405c3a2edc1a607df8340e9 (diff)
downloadrust-25face9808491588e59b6d7844f2185b09eef479.tar.gz
rust-25face9808491588e59b6d7844f2185b09eef479.zip
Auto merge of #143338 - matthiaskrgr:rollup-ykaxh04, r=matthiaskrgr
Rollup of 11 pull requests

Successful merges:

 - rust-lang/rust#131923 (Derive `Copy` and `Hash` for `IntErrorKind`)
 - rust-lang/rust#138340 (Remove some unsized tuple impls now that we don't support unsizing tuples anymore)
 - rust-lang/rust#141219 (Change `{Box,Arc,Rc,Weak}::into_raw` to only work with `A = Global`)
 - rust-lang/rust#142212 (bootstrap: validate `rust.codegen-backends` & `target.<triple>.codegen-backends`)
 - rust-lang/rust#142237 (Detect more cases of unused_parens around types)
 - rust-lang/rust#142964 (Attribute rework: a parser for single attributes without arguments)
 - rust-lang/rust#143070 (Rewrite `macro_rules!` parser to not use the MBE engine itself)
 - rust-lang/rust#143235 (Assemble const bounds via normal item bounds in old solver too)
 - rust-lang/rust#143261 (Feed `explicit_predicates_of` instead of `predicates_of`)
 - rust-lang/rust#143276 (loop match: handle opaque patterns)
 - rust-lang/rust#143306 (Add `track_caller` attributes to trace origin of Clippy lints)

r? `@ghost`
`@rustbot` modify labels: rollup

try-job: aarch64-apple
try-job: x86_64-msvc-1
try-job: x86_64-gnu
try-job: dist-i586-gnu-i586-i686-musl
try-job: test-various
Diffstat (limited to 'compiler/rustc_attr_parsing/src/attributes')
-rw-r--r--compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs51
-rw-r--r--compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs33
-rw-r--r--compiler/rustc_attr_parsing/src/attributes/loop_match.rs26
-rw-r--r--compiler/rustc_attr_parsing/src/attributes/mod.rs37
-rw-r--r--compiler/rustc_attr_parsing/src/attributes/semantics.rs20
-rw-r--r--compiler/rustc_attr_parsing/src/attributes/stability.rs18
6 files changed, 71 insertions, 114 deletions
diff --git a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs
index 7c412d4fa89..1132402ea00 100644
--- a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs
@@ -3,7 +3,10 @@ use rustc_feature::{AttributeTemplate, template};
 use rustc_session::parse::feature_err;
 use rustc_span::{Span, Symbol, sym};
 
-use super::{AcceptMapping, AttributeOrder, AttributeParser, OnDuplicate, SingleAttributeParser};
+use super::{
+    AcceptMapping, AttributeOrder, AttributeParser, NoArgsAttributeParser, OnDuplicate,
+    SingleAttributeParser,
+};
 use crate::context::{AcceptContext, FinalizeContext, Stage};
 use crate::parser::ArgParser;
 use crate::session_diagnostics::{NakedFunctionIncompatibleAttribute, NullOnExport};
@@ -43,20 +46,10 @@ impl<S: Stage> SingleAttributeParser<S> for OptimizeParser {
 
 pub(crate) struct ColdParser;
 
-impl<S: Stage> SingleAttributeParser<S> for ColdParser {
+impl<S: Stage> NoArgsAttributeParser<S> for ColdParser {
     const PATH: &[Symbol] = &[sym::cold];
-    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepLast;
     const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
-    const TEMPLATE: AttributeTemplate = template!(Word);
-
-    fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
-        if let Err(span) = args.no_args() {
-            cx.expected_no_args(span);
-            return None;
-        }
-
-        Some(AttributeKind::Cold(cx.attr_span))
-    }
+    const CREATE: fn(Span) -> AttributeKind = AttributeKind::Cold;
 }
 
 pub(crate) struct ExportNameParser;
@@ -194,39 +187,17 @@ impl<S: Stage> AttributeParser<S> for NakedParser {
 }
 
 pub(crate) struct TrackCallerParser;
-
-impl<S: Stage> SingleAttributeParser<S> for TrackCallerParser {
+impl<S: Stage> NoArgsAttributeParser<S> for TrackCallerParser {
     const PATH: &[Symbol] = &[sym::track_caller];
-    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepLast;
     const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
-    const TEMPLATE: AttributeTemplate = template!(Word);
-
-    fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
-        if let Err(span) = args.no_args() {
-            cx.expected_no_args(span);
-            return None;
-        }
-
-        Some(AttributeKind::TrackCaller(cx.attr_span))
-    }
+    const CREATE: fn(Span) -> AttributeKind = AttributeKind::TrackCaller;
 }
 
 pub(crate) struct NoMangleParser;
-
-impl<S: Stage> SingleAttributeParser<S> for NoMangleParser {
-    const PATH: &[rustc_span::Symbol] = &[sym::no_mangle];
-    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepLast;
+impl<S: Stage> NoArgsAttributeParser<S> for NoMangleParser {
+    const PATH: &[Symbol] = &[sym::no_mangle];
     const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
-    const TEMPLATE: AttributeTemplate = template!(Word);
-
-    fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
-        if let Err(span) = args.no_args() {
-            cx.expected_no_args(span);
-            return None;
-        }
-
-        Some(AttributeKind::NoMangle(cx.attr_span))
-    }
+    const CREATE: fn(Span) -> AttributeKind = AttributeKind::NoMangle;
 }
 
 #[derive(Default)]
diff --git a/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs b/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs
index 1c8fc5079da..5437803d781 100644
--- a/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs
@@ -1,38 +1,19 @@
 use rustc_attr_data_structures::AttributeKind;
-use rustc_feature::{AttributeTemplate, template};
-use rustc_span::{Symbol, sym};
+use rustc_span::{Span, Symbol, sym};
 
-use crate::attributes::{AttributeOrder, OnDuplicate, SingleAttributeParser};
-use crate::context::{AcceptContext, Stage};
-use crate::parser::ArgParser;
+use crate::attributes::{NoArgsAttributeParser, OnDuplicate};
+use crate::context::Stage;
 
 pub(crate) struct AsPtrParser;
-
-impl<S: Stage> SingleAttributeParser<S> for AsPtrParser {
+impl<S: Stage> NoArgsAttributeParser<S> for AsPtrParser {
     const PATH: &[Symbol] = &[sym::rustc_as_ptr];
-    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepFirst;
     const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
-    const TEMPLATE: AttributeTemplate = template!(Word);
-
-    fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
-        if let Err(span) = args.no_args() {
-            cx.expected_no_args(span);
-        }
-        Some(AttributeKind::AsPtr(cx.attr_span))
-    }
+    const CREATE: fn(Span) -> AttributeKind = AttributeKind::AsPtr;
 }
 
 pub(crate) struct PubTransparentParser;
-impl<S: Stage> SingleAttributeParser<S> for PubTransparentParser {
+impl<S: Stage> NoArgsAttributeParser<S> for PubTransparentParser {
     const PATH: &[Symbol] = &[sym::rustc_pub_transparent];
-    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepFirst;
     const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
-    const TEMPLATE: AttributeTemplate = template!(Word);
-
-    fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
-        if let Err(span) = args.no_args() {
-            cx.expected_no_args(span);
-        }
-        Some(AttributeKind::PubTransparent(cx.attr_span))
-    }
+    const CREATE: fn(Span) -> AttributeKind = AttributeKind::PubTransparent;
 }
diff --git a/compiler/rustc_attr_parsing/src/attributes/loop_match.rs b/compiler/rustc_attr_parsing/src/attributes/loop_match.rs
index f6c7ac5e3a3..80808b90dc6 100644
--- a/compiler/rustc_attr_parsing/src/attributes/loop_match.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/loop_match.rs
@@ -1,31 +1,19 @@
 use rustc_attr_data_structures::AttributeKind;
-use rustc_feature::{AttributeTemplate, template};
-use rustc_span::{Symbol, sym};
+use rustc_span::{Span, Symbol, sym};
 
-use crate::attributes::{AttributeOrder, OnDuplicate, SingleAttributeParser};
-use crate::context::{AcceptContext, Stage};
-use crate::parser::ArgParser;
+use crate::attributes::{NoArgsAttributeParser, OnDuplicate};
+use crate::context::Stage;
 
 pub(crate) struct LoopMatchParser;
-impl<S: Stage> SingleAttributeParser<S> for LoopMatchParser {
+impl<S: Stage> NoArgsAttributeParser<S> for LoopMatchParser {
     const PATH: &[Symbol] = &[sym::loop_match];
-    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepFirst;
     const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
-    const TEMPLATE: AttributeTemplate = template!(Word);
-
-    fn convert(cx: &mut AcceptContext<'_, '_, S>, _args: &ArgParser<'_>) -> Option<AttributeKind> {
-        Some(AttributeKind::LoopMatch(cx.attr_span))
-    }
+    const CREATE: fn(Span) -> AttributeKind = AttributeKind::LoopMatch;
 }
 
 pub(crate) struct ConstContinueParser;
-impl<S: Stage> SingleAttributeParser<S> for ConstContinueParser {
+impl<S: Stage> NoArgsAttributeParser<S> for ConstContinueParser {
     const PATH: &[Symbol] = &[sym::const_continue];
-    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepFirst;
     const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
-    const TEMPLATE: AttributeTemplate = template!(Word);
-
-    fn convert(cx: &mut AcceptContext<'_, '_, S>, _args: &ArgParser<'_>) -> Option<AttributeKind> {
-        Some(AttributeKind::ConstContinue(cx.attr_span))
-    }
+    const CREATE: fn(Span) -> AttributeKind = AttributeKind::ConstContinue;
 }
diff --git a/compiler/rustc_attr_parsing/src/attributes/mod.rs b/compiler/rustc_attr_parsing/src/attributes/mod.rs
index b3a9c69c055..f791d44e09a 100644
--- a/compiler/rustc_attr_parsing/src/attributes/mod.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/mod.rs
@@ -17,7 +17,7 @@
 use std::marker::PhantomData;
 
 use rustc_attr_data_structures::AttributeKind;
-use rustc_feature::AttributeTemplate;
+use rustc_feature::{AttributeTemplate, template};
 use rustc_span::{Span, Symbol};
 use thin_vec::ThinVec;
 
@@ -229,6 +229,41 @@ pub(crate) enum AttributeOrder {
     KeepLast,
 }
 
+/// An even simpler version of [`SingleAttributeParser`]:
+/// now automatically check that there are no arguments provided to the attribute.
+///
+/// [`WithoutArgs<T> where T: NoArgsAttributeParser`](WithoutArgs) implements [`SingleAttributeParser`].
+//
+pub(crate) trait NoArgsAttributeParser<S: Stage>: 'static {
+    const PATH: &[Symbol];
+    const ON_DUPLICATE: OnDuplicate<S>;
+
+    /// Create the [`AttributeKind`] given attribute's [`Span`].
+    const CREATE: fn(Span) -> AttributeKind;
+}
+
+pub(crate) struct WithoutArgs<T: NoArgsAttributeParser<S>, S: Stage>(PhantomData<(S, T)>);
+
+impl<T: NoArgsAttributeParser<S>, S: Stage> Default for WithoutArgs<T, S> {
+    fn default() -> Self {
+        Self(Default::default())
+    }
+}
+
+impl<T: NoArgsAttributeParser<S>, S: Stage> SingleAttributeParser<S> for WithoutArgs<T, S> {
+    const PATH: &[Symbol] = T::PATH;
+    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepLast;
+    const ON_DUPLICATE: OnDuplicate<S> = T::ON_DUPLICATE;
+    const TEMPLATE: AttributeTemplate = template!(Word);
+
+    fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
+        if let Err(span) = args.no_args() {
+            cx.expected_no_args(span);
+        }
+        Some(T::CREATE(cx.attr_span))
+    }
+}
+
 type ConvertFn<E> = fn(ThinVec<E>) -> AttributeKind;
 
 /// Alternative to [`AttributeParser`] that automatically handles state management.
diff --git a/compiler/rustc_attr_parsing/src/attributes/semantics.rs b/compiler/rustc_attr_parsing/src/attributes/semantics.rs
index 54f50445fbd..74fdff5d2e1 100644
--- a/compiler/rustc_attr_parsing/src/attributes/semantics.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/semantics.rs
@@ -1,22 +1,12 @@
 use rustc_attr_data_structures::AttributeKind;
-use rustc_feature::{AttributeTemplate, template};
-use rustc_span::{Symbol, sym};
+use rustc_span::{Span, Symbol, sym};
 
-use crate::attributes::{AttributeOrder, OnDuplicate, SingleAttributeParser};
-use crate::context::{AcceptContext, Stage};
-use crate::parser::ArgParser;
+use crate::attributes::{NoArgsAttributeParser, OnDuplicate};
+use crate::context::Stage;
 
 pub(crate) struct MayDangleParser;
-impl<S: Stage> SingleAttributeParser<S> for MayDangleParser {
+impl<S: Stage> NoArgsAttributeParser<S> for MayDangleParser {
     const PATH: &[Symbol] = &[sym::may_dangle];
-    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepFirst;
     const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
-    const TEMPLATE: AttributeTemplate = template!(Word);
-
-    fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
-        if let Err(span) = args.no_args() {
-            cx.expected_no_args(span);
-        }
-        Some(AttributeKind::MayDangle(cx.attr_span))
-    }
+    const CREATE: fn(span: Span) -> AttributeKind = AttributeKind::MayDangle;
 }
diff --git a/compiler/rustc_attr_parsing/src/attributes/stability.rs b/compiler/rustc_attr_parsing/src/attributes/stability.rs
index 37104855623..6bccd0042a8 100644
--- a/compiler/rustc_attr_parsing/src/attributes/stability.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/stability.rs
@@ -5,11 +5,12 @@ use rustc_attr_data_structures::{
     StableSince, UnstableReason, VERSION_PLACEHOLDER,
 };
 use rustc_errors::ErrorGuaranteed;
-use rustc_feature::{AttributeTemplate, template};
+use rustc_feature::template;
 use rustc_span::{Ident, Span, Symbol, sym};
 
 use super::util::parse_version;
-use super::{AcceptMapping, AttributeOrder, AttributeParser, OnDuplicate, SingleAttributeParser};
+use super::{AcceptMapping, AttributeParser, OnDuplicate};
+use crate::attributes::NoArgsAttributeParser;
 use crate::context::{AcceptContext, FinalizeContext, Stage};
 use crate::parser::{ArgParser, MetaItemParser};
 use crate::session_diagnostics::{self, UnsupportedLiteralReason};
@@ -132,19 +133,10 @@ impl<S: Stage> AttributeParser<S> for BodyStabilityParser {
 }
 
 pub(crate) struct ConstStabilityIndirectParser;
-// FIXME(jdonszelmann): single word attribute group when we have these
-impl<S: Stage> SingleAttributeParser<S> for ConstStabilityIndirectParser {
+impl<S: Stage> NoArgsAttributeParser<S> for ConstStabilityIndirectParser {
     const PATH: &[Symbol] = &[sym::rustc_const_stable_indirect];
-    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepFirst;
     const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Ignore;
-    const TEMPLATE: AttributeTemplate = template!(Word);
-
-    fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
-        if let Err(span) = args.no_args() {
-            cx.expected_no_args(span);
-        }
-        Some(AttributeKind::ConstStabilityIndirect)
-    }
+    const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::ConstStabilityIndirect;
 }
 
 #[derive(Default)]