]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_builtin_macros/src/cfg.rs
Rollup merge of #105359 - flba-eb:thread_local_key_sentinel_value, r=m-ou-se
[rust.git] / compiler / rustc_builtin_macros / src / cfg.rs
1 //! The compiler code necessary to support the cfg! extension, which expands to
2 //! a literal `true` or `false` based on whether the given cfg matches the
3 //! current compilation environment.
4
5 use rustc_ast as ast;
6 use rustc_ast::token;
7 use rustc_ast::tokenstream::TokenStream;
8 use rustc_attr as attr;
9 use rustc_errors::PResult;
10 use rustc_expand::base::{self, *};
11 use rustc_macros::Diagnostic;
12 use rustc_span::Span;
13
14 pub fn expand_cfg(
15     cx: &mut ExtCtxt<'_>,
16     sp: Span,
17     tts: TokenStream,
18 ) -> Box<dyn base::MacResult + 'static> {
19     let sp = cx.with_def_site_ctxt(sp);
20
21     match parse_cfg(cx, sp, tts) {
22         Ok(cfg) => {
23             let matches_cfg = attr::cfg_matches(
24                 &cfg,
25                 &cx.sess.parse_sess,
26                 cx.current_expansion.lint_node_id,
27                 cx.ecfg.features,
28             );
29             MacEager::expr(cx.expr_bool(sp, matches_cfg))
30         }
31         Err(mut err) => {
32             err.emit();
33             DummyResult::any(sp)
34         }
35     }
36 }
37
38 #[derive(Diagnostic)]
39 #[diag(builtin_macros_requires_cfg_pattern)]
40 struct RequiresCfgPattern {
41     #[primary_span]
42     #[label]
43     span: Span,
44 }
45
46 #[derive(Diagnostic)]
47 #[diag(builtin_macros_expected_one_cfg_pattern)]
48 struct OneCfgPattern {
49     #[primary_span]
50     span: Span,
51 }
52
53 fn parse_cfg<'a>(cx: &mut ExtCtxt<'a>, span: Span, tts: TokenStream) -> PResult<'a, ast::MetaItem> {
54     let mut p = cx.new_parser_from_tts(tts);
55
56     if p.token == token::Eof {
57         return Err(cx.create_err(RequiresCfgPattern { span }));
58     }
59
60     let cfg = p.parse_meta_item()?;
61
62     let _ = p.eat(&token::Comma);
63
64     if !p.eat(&token::Eof) {
65         return Err(cx.create_err(OneCfgPattern { span }));
66     }
67
68     Ok(cfg)
69 }