rustc_attr_parsing/attributes/
allow_unstable.rs

1use rustc_ast::attr::{AttributeExt, filter_by_name};
2use rustc_session::Session;
3use rustc_span::{Symbol, sym};
4
5use crate::session_diagnostics;
6
7pub fn allow_internal_unstable<'a>(
8    sess: &'a Session,
9    attrs: &'a [impl AttributeExt],
10) -> impl Iterator<Item = Symbol> + 'a {
11    allow_unstable(sess, attrs, sym::allow_internal_unstable)
12}
13
14pub fn rustc_allow_const_fn_unstable<'a>(
15    sess: &'a Session,
16    attrs: &'a [impl AttributeExt],
17) -> impl Iterator<Item = Symbol> + 'a {
18    allow_unstable(sess, attrs, sym::rustc_allow_const_fn_unstable)
19}
20
21fn allow_unstable<'a>(
22    sess: &'a Session,
23    attrs: &'a [impl AttributeExt],
24    symbol: Symbol,
25) -> impl Iterator<Item = Symbol> + 'a {
26    let attrs = filter_by_name(attrs, symbol);
27    let list = attrs
28        .filter_map(move |attr| {
29            attr.meta_item_list().or_else(|| {
30                sess.dcx().emit_err(session_diagnostics::ExpectsFeatureList {
31                    span: attr.span(),
32                    name: symbol.to_ident_string(),
33                });
34                None
35            })
36        })
37        .flatten();
38
39    list.into_iter().filter_map(move |it| {
40        let name = it.ident().map(|ident| ident.name);
41        if name.is_none() {
42            sess.dcx().emit_err(session_diagnostics::ExpectsFeatures {
43                span: it.span(),
44                name: symbol.to_ident_string(),
45            });
46        }
47        name
48    })
49}