rustc_builtin_macros/
cfg_accessible.rs1use rustc_ast as ast;
4use rustc_attr_parsing::{AttributeTemplate, validate_attr};
5use rustc_expand::base::{Annotatable, ExpandResult, ExtCtxt, Indeterminate, MultiItemModifier};
6use rustc_span::{Span, sym};
7
8use crate::diagnostics;
9
10pub(crate) struct Expander;
11
12fn validate_input<'a>(ecx: &ExtCtxt<'_>, mi: &'a ast::MetaItem) -> Option<&'a ast::Path> {
13 use diagnostics::CfgAccessibleInvalid::*;
14 match mi.meta_item_list() {
15 None => {}
16 Some([]) => {
17 ecx.dcx().emit_err(UnspecifiedPath(mi.span));
18 }
19 Some([_, .., l]) => {
20 ecx.dcx().emit_err(MultiplePaths(l.span()));
21 }
22 Some([nmi]) => match nmi.meta_item() {
23 None => {
24 ecx.dcx().emit_err(LiteralPath(nmi.span()));
25 }
26 Some(mi) => {
27 if !mi.is_word() {
28 ecx.dcx().emit_err(HasArguments(mi.span));
29 }
30 return Some(&mi.path);
31 }
32 },
33 }
34 None
35}
36
37impl MultiItemModifier for Expander {
38 fn expand(
39 &self,
40 ecx: &mut ExtCtxt<'_>,
41 span: Span,
42 meta_item: &ast::MetaItem,
43 item: Annotatable,
44 _is_derive_const: bool,
45 ) -> ExpandResult<Vec<Annotatable>, Annotatable> {
46 let template = AttributeTemplate { list: Some(&["path"]), ..Default::default() };
47 validate_attr::check_builtin_meta_item(
48 &ecx.sess.psess,
49 meta_item,
50 ast::AttrStyle::Outer,
51 sym::cfg_accessible,
52 template,
53 true,
54 );
55
56 let Some(path) = validate_input(ecx, meta_item) else {
57 return ExpandResult::Ready(Vec::new());
58 };
59
60 match ecx.resolver.cfg_accessible(ecx.current_expansion.id, path) {
61 Ok(true) => ExpandResult::Ready(::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[item]))vec![item]),
62 Ok(false) => ExpandResult::Ready(Vec::new()),
63 Err(Indeterminate) if ecx.force_mode => {
64 ecx.dcx().emit_err(diagnostics::CfgAccessibleIndeterminate { span });
65 ExpandResult::Ready(::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[item]))vec![item])
66 }
67 Err(Indeterminate) => ExpandResult::Retry(item),
68 }
69 }
70}