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}