mirror of
https://github.com/rust-lang/rust.git
synced 2025-12-02 14:48:04 +00:00
Port cfg!() macro to the new attribute parsing system
Signed-off-by: Jonathan Brouwer <jonathantbrouwer@gmail.com>
This commit is contained in:
parent
001be2fab4
commit
b78800fd5d
@ -50,7 +50,7 @@ pub fn parse_cfg<'c, S: Stage>(
|
||||
parse_cfg_entry(cx, single).ok()
|
||||
}
|
||||
|
||||
pub(crate) fn parse_cfg_entry<S: Stage>(
|
||||
pub fn parse_cfg_entry<S: Stage>(
|
||||
cx: &mut AcceptContext<'_, '_, S>,
|
||||
item: &MetaItemOrLitParser<'_>,
|
||||
) -> Result<CfgEntry, ErrorGuaranteed> {
|
||||
|
||||
@ -106,7 +106,7 @@ mod target_checking;
|
||||
pub mod validate_attr;
|
||||
|
||||
pub use attributes::cfg::{
|
||||
CFG_TEMPLATE, EvalConfigResult, eval_config_entry, parse_cfg, parse_cfg_attr,
|
||||
CFG_TEMPLATE, EvalConfigResult, eval_config_entry, parse_cfg, parse_cfg_attr, parse_cfg_entry,
|
||||
};
|
||||
pub use attributes::cfg_old::*;
|
||||
pub use attributes::util::{is_builtin_attr, is_doc_alias_attrs_contain_symbol, parse_version};
|
||||
|
||||
@ -2,13 +2,16 @@
|
||||
//! a literal `true` or `false` based on whether the given cfg matches the
|
||||
//! current compilation environment.
|
||||
|
||||
use rustc_ast::token;
|
||||
use rustc_ast::tokenstream::TokenStream;
|
||||
use rustc_errors::PResult;
|
||||
use rustc_ast::{AttrStyle, CRATE_NODE_ID, token};
|
||||
use rustc_attr_parsing as attr;
|
||||
use rustc_attr_parsing::parser::MetaItemOrLitParser;
|
||||
use rustc_attr_parsing::{AttributeParser, CFG_TEMPLATE, ShouldEmit, parse_cfg_entry};
|
||||
use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacEager, MacroExpanderResult};
|
||||
use rustc_hir::AttrPath;
|
||||
use rustc_hir::attrs::CfgEntry;
|
||||
use rustc_parse::exp;
|
||||
use rustc_span::Span;
|
||||
use {rustc_ast as ast, rustc_attr_parsing as attr};
|
||||
use rustc_span::{ErrorGuaranteed, Ident, Span};
|
||||
|
||||
use crate::errors;
|
||||
|
||||
@ -21,38 +24,48 @@ pub(crate) fn expand_cfg(
|
||||
|
||||
ExpandResult::Ready(match parse_cfg(cx, sp, tts) {
|
||||
Ok(cfg) => {
|
||||
let matches_cfg = attr::cfg_matches(
|
||||
let matches_cfg = attr::eval_config_entry(
|
||||
cx.sess,
|
||||
&cfg,
|
||||
&cx.sess,
|
||||
cx.current_expansion.lint_node_id,
|
||||
Some(cx.ecfg.features),
|
||||
);
|
||||
ShouldEmit::ErrorsAndLints,
|
||||
)
|
||||
.as_bool();
|
||||
|
||||
MacEager::expr(cx.expr_bool(sp, matches_cfg))
|
||||
}
|
||||
Err(err) => {
|
||||
let guar = err.emit();
|
||||
DummyResult::any(sp, guar)
|
||||
}
|
||||
Err(guar) => DummyResult::any(sp, guar),
|
||||
})
|
||||
}
|
||||
|
||||
fn parse_cfg<'a>(
|
||||
cx: &ExtCtxt<'a>,
|
||||
span: Span,
|
||||
tts: TokenStream,
|
||||
) -> PResult<'a, ast::MetaItemInner> {
|
||||
let mut p = cx.new_parser_from_tts(tts);
|
||||
|
||||
if p.token == token::Eof {
|
||||
return Err(cx.dcx().create_err(errors::RequiresCfgPattern { span }));
|
||||
fn parse_cfg(cx: &ExtCtxt<'_>, span: Span, tts: TokenStream) -> Result<CfgEntry, ErrorGuaranteed> {
|
||||
let mut parser = cx.new_parser_from_tts(tts);
|
||||
if parser.token == token::Eof {
|
||||
return Err(cx.dcx().emit_err(errors::RequiresCfgPattern { span }));
|
||||
}
|
||||
|
||||
let cfg = p.parse_meta_item_inner()?;
|
||||
let meta = MetaItemOrLitParser::parse_single(&mut parser, ShouldEmit::ErrorsAndLints)
|
||||
.map_err(|diag| diag.emit())?;
|
||||
let cfg = AttributeParser::parse_single_args(
|
||||
cx.sess,
|
||||
span,
|
||||
span,
|
||||
AttrStyle::Inner,
|
||||
AttrPath { segments: vec![Ident::from_str("cfg")].into_boxed_slice(), span },
|
||||
span,
|
||||
CRATE_NODE_ID,
|
||||
Some(cx.ecfg.features),
|
||||
ShouldEmit::ErrorsAndLints,
|
||||
&meta,
|
||||
parse_cfg_entry,
|
||||
&CFG_TEMPLATE,
|
||||
)?;
|
||||
|
||||
let _ = p.eat(exp!(Comma));
|
||||
let _ = parser.eat(exp!(Comma));
|
||||
|
||||
if !p.eat(exp!(Eof)) {
|
||||
return Err(cx.dcx().create_err(errors::OneCfgPattern { span }));
|
||||
if !parser.eat(exp!(Eof)) {
|
||||
return Err(cx.dcx().emit_err(errors::OneCfgPattern { span }));
|
||||
}
|
||||
|
||||
Ok(cfg)
|
||||
|
||||
@ -1,18 +1,22 @@
|
||||
The `not` cfg-predicate was malformed.
|
||||
|
||||
Erroneous code example:
|
||||
Erroneous code example (using `cargo doc`):
|
||||
|
||||
```compile_fail,E0536
|
||||
```ignore, E0536 (only triggers on cargo doc)
|
||||
#![feature(doc_cfg)]
|
||||
#[doc(cfg(not()))]
|
||||
pub fn main() {
|
||||
if cfg!(not()) { }
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
The `not` predicate expects one cfg-pattern. Example:
|
||||
|
||||
```
|
||||
#![feature(doc_cfg)]
|
||||
#[doc(cfg(not(target_os = "linux")))] // ok!
|
||||
pub fn main() {
|
||||
if cfg!(not(target_os = "linux")) { } // ok!
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
fn main() {
|
||||
cfg!(); //~ ERROR macro requires a cfg-pattern
|
||||
cfg!(123); //~ ERROR literal in `cfg` predicate value must be a boolean
|
||||
cfg!(foo = 123); //~ ERROR literal in `cfg` predicate value must be a string
|
||||
cfg!(123); //~ ERROR malformed `cfg` attribute input
|
||||
cfg!(foo = 123); //~ ERROR malformed `cfg` attribute input
|
||||
cfg!(foo, bar); //~ ERROR expected 1 cfg-pattern
|
||||
}
|
||||
|
||||
@ -4,17 +4,27 @@ error: macro requires a cfg-pattern as an argument
|
||||
LL | cfg!();
|
||||
| ^^^^^^ cfg-pattern required
|
||||
|
||||
error[E0565]: literal in `cfg` predicate value must be a boolean
|
||||
--> $DIR/cfg.rs:3:10
|
||||
error[E0539]: malformed `cfg` attribute input
|
||||
--> $DIR/cfg.rs:3:5
|
||||
|
|
||||
LL | cfg!(123);
|
||||
| ^^^
|
||||
| ^^^^^---^
|
||||
| | |
|
||||
| | expected a valid identifier here
|
||||
| help: must be of the form: `cfg(predicate)`
|
||||
|
|
||||
= note: for more information, visit <https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg-attribute>
|
||||
|
||||
error[E0565]: literal in `cfg` predicate value must be a string
|
||||
--> $DIR/cfg.rs:4:16
|
||||
error[E0539]: malformed `cfg` attribute input
|
||||
--> $DIR/cfg.rs:4:5
|
||||
|
|
||||
LL | cfg!(foo = 123);
|
||||
| ^^^
|
||||
| ^^^^^^^^^^^---^
|
||||
| | |
|
||||
| | expected a string literal here
|
||||
| help: must be of the form: `cfg(predicate)`
|
||||
|
|
||||
= note: for more information, visit <https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg-attribute>
|
||||
|
||||
error: expected 1 cfg-pattern
|
||||
--> $DIR/cfg.rs:5:5
|
||||
@ -24,4 +34,4 @@ LL | cfg!(foo, bar);
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0565`.
|
||||
For more information about this error, try `rustc --explain E0539`.
|
||||
|
||||
@ -1,3 +0,0 @@
|
||||
pub fn main() {
|
||||
if cfg!(not()) { } //~ ERROR E0536
|
||||
}
|
||||
@ -1,9 +0,0 @@
|
||||
error[E0536]: expected 1 cfg-pattern
|
||||
--> $DIR/E0536.rs:2:13
|
||||
|
|
||||
LL | if cfg!(not()) { }
|
||||
| ^^^^^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0536`.
|
||||
3
tests/ui/span/E0805.rs
Normal file
3
tests/ui/span/E0805.rs
Normal file
@ -0,0 +1,3 @@
|
||||
pub fn main() {
|
||||
if cfg!(not()) { } //~ ERROR E0805
|
||||
}
|
||||
14
tests/ui/span/E0805.stderr
Normal file
14
tests/ui/span/E0805.stderr
Normal file
@ -0,0 +1,14 @@
|
||||
error[E0805]: malformed `cfg` attribute input
|
||||
--> $DIR/E0805.rs:2:8
|
||||
|
|
||||
LL | if cfg!(not()) { }
|
||||
| ^^^^^^^^--^
|
||||
| | |
|
||||
| | expected a single argument here
|
||||
| help: must be of the form: `cfg(predicate)`
|
||||
|
|
||||
= note: for more information, visit <https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg-attribute>
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0805`.
|
||||
Loading…
x
Reference in New Issue
Block a user