about summary refs log tree commit diff
path: root/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs
diff options
context:
space:
mode:
authorJana Dönszelmann <jana@donsz.nl>2025-02-09 22:49:33 +0100
committerJana Dönszelmann <jana@donsz.nl>2025-02-24 14:31:17 +0100
commit7e0f5b50168c63bd1879067c043559ef0f01671e (patch)
treeb2f1b1f68ef89985faec8ae287731613e4b520c4 /compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs
parentdbd3b7928e91758296a0f6093d72f90214888133 (diff)
downloadrust-7e0f5b50168c63bd1879067c043559ef0f01671e.tar.gz
rust-7e0f5b50168c63bd1879067c043559ef0f01671e.zip
Introduce new-style attribute parsers for several attributes
note: compiler compiles but librustdoc and clippy don't
Diffstat (limited to 'compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs')
-rw-r--r--compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs92
1 files changed, 55 insertions, 37 deletions
diff --git a/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs b/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs
index 13d246b08a8..d37ede86cfd 100644
--- a/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs
@@ -1,49 +1,67 @@
-use rustc_ast::attr::{AttributeExt, filter_by_name};
-use rustc_session::Session;
-use rustc_span::{Symbol, sym};
+use std::iter;
 
+use rustc_attr_data_structures::AttributeKind;
+use rustc_span::{Span, Symbol, sym};
+
+use super::{CombineAttributeParser, ConvertFn};
+use crate::context::AcceptContext;
+use crate::parser::ArgParser;
 use crate::session_diagnostics;
 
-pub fn allow_internal_unstable(
-    sess: &Session,
-    attrs: &[impl AttributeExt],
-) -> impl Iterator<Item = Symbol> {
-    allow_unstable(sess, attrs, sym::allow_internal_unstable)
+pub(crate) struct AllowInternalUnstableParser;
+impl CombineAttributeParser for AllowInternalUnstableParser {
+    const PATH: &'static [rustc_span::Symbol] = &[sym::allow_internal_unstable];
+    type Item = (Symbol, Span);
+    const CONVERT: ConvertFn<Self::Item> = AttributeKind::AllowInternalUnstable;
+
+    fn extend<'a>(
+        cx: &'a AcceptContext<'a>,
+        args: &'a ArgParser<'a>,
+    ) -> impl IntoIterator<Item = Self::Item> + 'a {
+        parse_unstable(cx, args, Self::PATH[0]).into_iter().zip(iter::repeat(cx.attr_span))
+    }
 }
 
-pub fn rustc_allow_const_fn_unstable(
-    sess: &Session,
-    attrs: &[impl AttributeExt],
-) -> impl Iterator<Item = Symbol> {
-    allow_unstable(sess, attrs, sym::rustc_allow_const_fn_unstable)
+pub(crate) struct AllowConstFnUnstableParser;
+impl CombineAttributeParser for AllowConstFnUnstableParser {
+    const PATH: &'static [rustc_span::Symbol] = &[sym::rustc_allow_const_fn_unstable];
+    type Item = Symbol;
+    const CONVERT: ConvertFn<Self::Item> = AttributeKind::AllowConstFnUnstable;
+
+    fn extend<'a>(
+        cx: &'a AcceptContext<'a>,
+        args: &'a ArgParser<'a>,
+    ) -> impl IntoIterator<Item = Self::Item> + 'a {
+        parse_unstable(cx, args, Self::PATH[0])
+    }
 }
 
-fn allow_unstable(
-    sess: &Session,
-    attrs: &[impl AttributeExt],
+fn parse_unstable<'a>(
+    cx: &AcceptContext<'_>,
+    args: &'a ArgParser<'a>,
     symbol: Symbol,
-) -> impl Iterator<Item = Symbol> {
-    let attrs = filter_by_name(attrs, symbol);
-    let list = attrs
-        .filter_map(move |attr| {
-            attr.meta_item_list().or_else(|| {
-                sess.dcx().emit_err(session_diagnostics::ExpectsFeatureList {
-                    span: attr.span(),
-                    name: symbol.to_ident_string(),
-                });
-                None
-            })
-        })
-        .flatten();
-
-    list.into_iter().filter_map(move |it| {
-        let name = it.ident().map(|ident| ident.name);
-        if name.is_none() {
-            sess.dcx().emit_err(session_diagnostics::ExpectsFeatures {
-                span: it.span(),
+) -> impl IntoIterator<Item = Symbol> {
+    let mut res = Vec::new();
+
+    let Some(list) = args.list() else {
+        cx.emit_err(session_diagnostics::ExpectsFeatureList {
+            span: cx.attr_span,
+            name: symbol.to_ident_string(),
+        });
+        return res;
+    };
+
+    for param in list.mixed() {
+        let param_span = param.span();
+        if let Some(ident) = param.meta_item().and_then(|i| i.word_without_args()) {
+            res.push(ident.name);
+        } else {
+            cx.emit_err(session_diagnostics::ExpectsFeatures {
+                span: param_span,
                 name: symbol.to_ident_string(),
             });
         }
-        name
-    })
+    }
+
+    res
 }