diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:02:58 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:02:58 +0000 |
commit | 698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch) | |
tree | 173a775858bd501c378080a10dca74132f05bc50 /compiler/rustc_builtin_macros/src/cfg.rs | |
parent | Initial commit. (diff) | |
download | rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip |
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_builtin_macros/src/cfg.rs')
-rw-r--r-- | compiler/rustc_builtin_macros/src/cfg.rs | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/compiler/rustc_builtin_macros/src/cfg.rs b/compiler/rustc_builtin_macros/src/cfg.rs new file mode 100644 index 000000000..aa355150b --- /dev/null +++ b/compiler/rustc_builtin_macros/src/cfg.rs @@ -0,0 +1,69 @@ +//! The compiler code necessary to support the cfg! extension, which expands to +//! a literal `true` or `false` based on whether the given cfg matches the +//! current compilation environment. + +use rustc_ast as ast; +use rustc_ast::token; +use rustc_ast::tokenstream::TokenStream; +use rustc_attr as attr; +use rustc_errors::PResult; +use rustc_expand::base::{self, *}; +use rustc_macros::SessionDiagnostic; +use rustc_span::Span; + +pub fn expand_cfg( + cx: &mut ExtCtxt<'_>, + sp: Span, + tts: TokenStream, +) -> Box<dyn base::MacResult + 'static> { + let sp = cx.with_def_site_ctxt(sp); + + match parse_cfg(cx, sp, tts) { + Ok(cfg) => { + let matches_cfg = attr::cfg_matches( + &cfg, + &cx.sess.parse_sess, + cx.current_expansion.lint_node_id, + cx.ecfg.features, + ); + MacEager::expr(cx.expr_bool(sp, matches_cfg)) + } + Err(mut err) => { + err.emit(); + DummyResult::any(sp) + } + } +} + +#[derive(SessionDiagnostic)] +#[error(builtin_macros::requires_cfg_pattern)] +struct RequiresCfgPattern { + #[primary_span] + #[label] + span: Span, +} + +#[derive(SessionDiagnostic)] +#[error(builtin_macros::expected_one_cfg_pattern)] +struct OneCfgPattern { + #[primary_span] + span: Span, +} + +fn parse_cfg<'a>(cx: &mut ExtCtxt<'a>, span: Span, tts: TokenStream) -> PResult<'a, ast::MetaItem> { + let mut p = cx.new_parser_from_tts(tts); + + if p.token == token::Eof { + return Err(cx.create_err(RequiresCfgPattern { span })); + } + + let cfg = p.parse_meta_item()?; + + let _ = p.eat(&token::Comma); + + if !p.eat(&token::Eof) { + return Err(cx.create_err(OneCfgPattern { span })); + } + + Ok(cfg) +} |