about summary refs log tree commit diff
path: root/compiler/rustc_attr_parsing/src/attributes/mod.rs
diff options
context:
space:
mode:
authorPavel Grigorenko <GrigorenkoPV@ya.ru>2025-06-19 02:05:47 +0300
committerPavel Grigorenko <GrigorenkoPV@ya.ru>2025-06-30 23:19:04 +0300
commit187babc35f07153e2853ee9b6984f56aa158abc5 (patch)
treef1415133c4d9d5ed2bba6cedc54771fe9591af1b /compiler/rustc_attr_parsing/src/attributes/mod.rs
parentc65dccabacdfd6c8a7f7439eba13422fdd89b91e (diff)
downloadrust-187babc35f07153e2853ee9b6984f56aa158abc5.tar.gz
rust-187babc35f07153e2853ee9b6984f56aa158abc5.zip
NoArgsAttributeParser
Diffstat (limited to 'compiler/rustc_attr_parsing/src/attributes/mod.rs')
-rw-r--r--compiler/rustc_attr_parsing/src/attributes/mod.rs37
1 files changed, 36 insertions, 1 deletions
diff --git a/compiler/rustc_attr_parsing/src/attributes/mod.rs b/compiler/rustc_attr_parsing/src/attributes/mod.rs
index 584dadadcf7..abddc75ab8b 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;
 
@@ -228,6 +228,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`].
+    fn create(span: 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.