Skip to content

Commit b78800f

Browse files
Port cfg!() macro to the new attribute parsing system
Signed-off-by: Jonathan Brouwer <jonathantbrouwer@gmail.com>
1 parent 001be2f commit b78800f

File tree

10 files changed

+83
-51
lines changed

10 files changed

+83
-51
lines changed

compiler/rustc_attr_parsing/src/attributes/cfg.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ pub fn parse_cfg<'c, S: Stage>(
5050
parse_cfg_entry(cx, single).ok()
5151
}
5252

53-
pub(crate) fn parse_cfg_entry<S: Stage>(
53+
pub fn parse_cfg_entry<S: Stage>(
5454
cx: &mut AcceptContext<'_, '_, S>,
5555
item: &MetaItemOrLitParser<'_>,
5656
) -> Result<CfgEntry, ErrorGuaranteed> {

compiler/rustc_attr_parsing/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ mod target_checking;
106106
pub mod validate_attr;
107107

108108
pub use attributes::cfg::{
109-
CFG_TEMPLATE, EvalConfigResult, eval_config_entry, parse_cfg, parse_cfg_attr,
109+
CFG_TEMPLATE, EvalConfigResult, eval_config_entry, parse_cfg, parse_cfg_attr, parse_cfg_entry,
110110
};
111111
pub use attributes::cfg_old::*;
112112
pub use attributes::util::{is_builtin_attr, is_doc_alias_attrs_contain_symbol, parse_version};

compiler/rustc_builtin_macros/src/cfg.rs

Lines changed: 37 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,16 @@
22
//! a literal `true` or `false` based on whether the given cfg matches the
33
//! current compilation environment.
44
5-
use rustc_ast::token;
65
use rustc_ast::tokenstream::TokenStream;
7-
use rustc_errors::PResult;
6+
use rustc_ast::{AttrStyle, CRATE_NODE_ID, token};
7+
use rustc_attr_parsing as attr;
8+
use rustc_attr_parsing::parser::MetaItemOrLitParser;
9+
use rustc_attr_parsing::{AttributeParser, CFG_TEMPLATE, ShouldEmit, parse_cfg_entry};
810
use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacEager, MacroExpanderResult};
11+
use rustc_hir::AttrPath;
12+
use rustc_hir::attrs::CfgEntry;
913
use rustc_parse::exp;
10-
use rustc_span::Span;
11-
use {rustc_ast as ast, rustc_attr_parsing as attr};
14+
use rustc_span::{ErrorGuaranteed, Ident, Span};
1215

1316
use crate::errors;
1417

@@ -21,38 +24,48 @@ pub(crate) fn expand_cfg(
2124

2225
ExpandResult::Ready(match parse_cfg(cx, sp, tts) {
2326
Ok(cfg) => {
24-
let matches_cfg = attr::cfg_matches(
27+
let matches_cfg = attr::eval_config_entry(
28+
cx.sess,
2529
&cfg,
26-
&cx.sess,
2730
cx.current_expansion.lint_node_id,
2831
Some(cx.ecfg.features),
29-
);
32+
ShouldEmit::ErrorsAndLints,
33+
)
34+
.as_bool();
35+
3036
MacEager::expr(cx.expr_bool(sp, matches_cfg))
3137
}
32-
Err(err) => {
33-
let guar = err.emit();
34-
DummyResult::any(sp, guar)
35-
}
38+
Err(guar) => DummyResult::any(sp, guar),
3639
})
3740
}
3841

39-
fn parse_cfg<'a>(
40-
cx: &ExtCtxt<'a>,
41-
span: Span,
42-
tts: TokenStream,
43-
) -> PResult<'a, ast::MetaItemInner> {
44-
let mut p = cx.new_parser_from_tts(tts);
45-
46-
if p.token == token::Eof {
47-
return Err(cx.dcx().create_err(errors::RequiresCfgPattern { span }));
42+
fn parse_cfg(cx: &ExtCtxt<'_>, span: Span, tts: TokenStream) -> Result<CfgEntry, ErrorGuaranteed> {
43+
let mut parser = cx.new_parser_from_tts(tts);
44+
if parser.token == token::Eof {
45+
return Err(cx.dcx().emit_err(errors::RequiresCfgPattern { span }));
4846
}
4947

50-
let cfg = p.parse_meta_item_inner()?;
48+
let meta = MetaItemOrLitParser::parse_single(&mut parser, ShouldEmit::ErrorsAndLints)
49+
.map_err(|diag| diag.emit())?;
50+
let cfg = AttributeParser::parse_single_args(
51+
cx.sess,
52+
span,
53+
span,
54+
AttrStyle::Inner,
55+
AttrPath { segments: vec![Ident::from_str("cfg")].into_boxed_slice(), span },
56+
span,
57+
CRATE_NODE_ID,
58+
Some(cx.ecfg.features),
59+
ShouldEmit::ErrorsAndLints,
60+
&meta,
61+
parse_cfg_entry,
62+
&CFG_TEMPLATE,
63+
)?;
5164

52-
let _ = p.eat(exp!(Comma));
65+
let _ = parser.eat(exp!(Comma));
5366

54-
if !p.eat(exp!(Eof)) {
55-
return Err(cx.dcx().create_err(errors::OneCfgPattern { span }));
67+
if !parser.eat(exp!(Eof)) {
68+
return Err(cx.dcx().emit_err(errors::OneCfgPattern { span }));
5669
}
5770

5871
Ok(cfg)

compiler/rustc_error_codes/src/error_codes/E0536.md

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,22 @@
11
The `not` cfg-predicate was malformed.
22

3-
Erroneous code example:
3+
Erroneous code example (using `cargo doc`):
44

5-
```compile_fail,E0536
5+
```ignore, E0536 (only triggers on cargo doc)
6+
#![feature(doc_cfg)]
7+
#[doc(cfg(not()))]
68
pub fn main() {
7-
if cfg!(not()) { }
9+
810
}
911
```
1012

1113
The `not` predicate expects one cfg-pattern. Example:
1214

1315
```
16+
#![feature(doc_cfg)]
17+
#[doc(cfg(not(target_os = "linux")))] // ok!
1418
pub fn main() {
15-
if cfg!(not(target_os = "linux")) { } // ok!
19+
1620
}
1721
```
1822

tests/ui/macros/cfg.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
fn main() {
22
cfg!(); //~ ERROR macro requires a cfg-pattern
3-
cfg!(123); //~ ERROR literal in `cfg` predicate value must be a boolean
4-
cfg!(foo = 123); //~ ERROR literal in `cfg` predicate value must be a string
3+
cfg!(123); //~ ERROR malformed `cfg` attribute input
4+
cfg!(foo = 123); //~ ERROR malformed `cfg` attribute input
55
cfg!(foo, bar); //~ ERROR expected 1 cfg-pattern
66
}

tests/ui/macros/cfg.stderr

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,27 @@ error: macro requires a cfg-pattern as an argument
44
LL | cfg!();
55
| ^^^^^^ cfg-pattern required
66

7-
error[E0565]: literal in `cfg` predicate value must be a boolean
8-
--> $DIR/cfg.rs:3:10
7+
error[E0539]: malformed `cfg` attribute input
8+
--> $DIR/cfg.rs:3:5
99
|
1010
LL | cfg!(123);
11-
| ^^^
11+
| ^^^^^---^
12+
| | |
13+
| | expected a valid identifier here
14+
| help: must be of the form: `cfg(predicate)`
15+
|
16+
= note: for more information, visit <https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg-attribute>
1217

13-
error[E0565]: literal in `cfg` predicate value must be a string
14-
--> $DIR/cfg.rs:4:16
18+
error[E0539]: malformed `cfg` attribute input
19+
--> $DIR/cfg.rs:4:5
1520
|
1621
LL | cfg!(foo = 123);
17-
| ^^^
22+
| ^^^^^^^^^^^---^
23+
| | |
24+
| | expected a string literal here
25+
| help: must be of the form: `cfg(predicate)`
26+
|
27+
= note: for more information, visit <https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg-attribute>
1828

1929
error: expected 1 cfg-pattern
2030
--> $DIR/cfg.rs:5:5
@@ -24,4 +34,4 @@ LL | cfg!(foo, bar);
2434

2535
error: aborting due to 4 previous errors
2636

27-
For more information about this error, try `rustc --explain E0565`.
37+
For more information about this error, try `rustc --explain E0539`.

tests/ui/span/E0536.rs

Lines changed: 0 additions & 3 deletions
This file was deleted.

tests/ui/span/E0536.stderr

Lines changed: 0 additions & 9 deletions
This file was deleted.

tests/ui/span/E0805.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
pub fn main() {
2+
if cfg!(not()) { } //~ ERROR E0805
3+
}

tests/ui/span/E0805.stderr

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error[E0805]: malformed `cfg` attribute input
2+
--> $DIR/E0805.rs:2:8
3+
|
4+
LL | if cfg!(not()) { }
5+
| ^^^^^^^^--^
6+
| | |
7+
| | expected a single argument here
8+
| help: must be of the form: `cfg(predicate)`
9+
|
10+
= note: for more information, visit <https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg-attribute>
11+
12+
error: aborting due to 1 previous error
13+
14+
For more information about this error, try `rustc --explain E0805`.

0 commit comments

Comments
 (0)