diff options
Diffstat (limited to 'compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs')
| -rw-r--r-- | compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs | 92 |
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 471168ed4f5..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<'a>( - sess: &'a Session, - attrs: &'a [impl AttributeExt], -) -> impl Iterator<Item = Symbol> + 'a { - 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<'a>( - sess: &'a Session, - attrs: &'a [impl AttributeExt], -) -> impl Iterator<Item = Symbol> + 'a { - 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<'a>( - sess: &'a Session, - attrs: &'a [impl AttributeExt], +fn parse_unstable<'a>( + cx: &AcceptContext<'_>, + args: &'a ArgParser<'a>, symbol: Symbol, -) -> impl Iterator<Item = Symbol> + 'a { - 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 } |
