]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_builtin_macros/src/cfg.rs
Rollup merge of #95214 - tbu-:pr_vec_append_doc, r=Mark-Simulacrum
[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_span::Span;
12
13 pub fn expand_cfg(
14     cx: &mut ExtCtxt<'_>,
15     sp: Span,
16     tts: TokenStream,
17 ) -> Box<dyn base::MacResult + 'static> {
18     let sp = cx.with_def_site_ctxt(sp);
19
20     match parse_cfg(cx, sp, tts) {
21         Ok(cfg) => {
22             let matches_cfg = attr::cfg_matches(
23                 &cfg,
24                 &cx.sess.parse_sess,
25                 cx.current_expansion.lint_node_id,
26                 cx.ecfg.features,
27             );
28             MacEager::expr(cx.expr_bool(sp, matches_cfg))
29         }
30         Err(mut err) => {
31             err.emit();
32             DummyResult::any(sp)
33         }
34     }
35 }
36
37 fn parse_cfg<'a>(cx: &mut ExtCtxt<'a>, sp: Span, tts: TokenStream) -> PResult<'a, ast::MetaItem> {
38     let mut p = cx.new_parser_from_tts(tts);
39
40     if p.token == token::Eof {
41         let mut err = cx.struct_span_err(sp, "macro requires a cfg-pattern as an argument");
42         err.span_label(sp, "cfg-pattern required");
43         return Err(err);
44     }
45
46     let cfg = p.parse_meta_item()?;
47
48     let _ = p.eat(&token::Comma);
49
50     if !p.eat(&token::Eof) {
51         return Err(cx.struct_span_err(sp, "expected 1 cfg-pattern"));
52     }
53
54     Ok(cfg)
55 }