Skip to content

Commit 81067e9

Browse files
committed
Use ast::NestedMetaItem when evaluating cfg predicate
1 parent c3ce4e6 commit 81067e9

File tree

11 files changed

+62
-35
lines changed

11 files changed

+62
-35
lines changed

compiler/rustc_attr/src/builtin.rs

+25-10
Original file line numberDiff line numberDiff line change
@@ -523,7 +523,7 @@ pub struct Condition {
523523

524524
/// Tests if a cfg-pattern matches the cfg set
525525
pub fn cfg_matches(
526-
cfg: &ast::MetaItem,
526+
cfg: &ast::NestedMetaItem,
527527
sess: &Session,
528528
lint_node_id: NodeId,
529529
features: Option<&Features>,
@@ -594,12 +594,26 @@ pub fn parse_version(s: Symbol) -> Option<RustcVersion> {
594594
/// Evaluate a cfg-like condition (with `any` and `all`), using `eval` to
595595
/// evaluate individual items.
596596
pub fn eval_condition(
597-
cfg: &ast::MetaItem,
597+
cfg: &ast::NestedMetaItem,
598598
sess: &Session,
599599
features: Option<&Features>,
600600
eval: &mut impl FnMut(Condition) -> bool,
601601
) -> bool {
602602
let dcx = sess.dcx();
603+
604+
let cfg = match cfg {
605+
ast::NestedMetaItem::MetaItem(meta_item) => meta_item,
606+
_ => {
607+
dcx.emit_err(session_diagnostics::UnsupportedLiteral {
608+
span: cfg.span(),
609+
reason: UnsupportedLiteralReason::Generic,
610+
is_bytestr: false,
611+
start_point_span: sess.source_map().start_point(cfg.span()),
612+
});
613+
return false;
614+
}
615+
};
616+
603617
match &cfg.kind {
604618
ast::MetaItemKind::List(mis) if cfg.name_or_empty() == sym::version => {
605619
try_gate_cfg(sym::version, cfg.span, sess, features);
@@ -653,23 +667,19 @@ pub fn eval_condition(
653667
.iter()
654668
// We don't use any() here, because we want to evaluate all cfg condition
655669
// as eval_condition can (and does) extra checks
656-
.fold(false, |res, mi| {
657-
res | eval_condition(mi.meta_item().unwrap(), sess, features, eval)
658-
}),
670+
.fold(false, |res, mi| res | eval_condition(mi, sess, features, eval)),
659671
sym::all => mis
660672
.iter()
661673
// We don't use all() here, because we want to evaluate all cfg condition
662674
// as eval_condition can (and does) extra checks
663-
.fold(true, |res, mi| {
664-
res & eval_condition(mi.meta_item().unwrap(), sess, features, eval)
665-
}),
675+
.fold(true, |res, mi| res & eval_condition(mi, sess, features, eval)),
666676
sym::not => {
667677
let [mi] = mis.as_slice() else {
668678
dcx.emit_err(session_diagnostics::ExpectedOneCfgPattern { span: cfg.span });
669679
return false;
670680
};
671681

672-
!eval_condition(mi.meta_item().unwrap(), sess, features, eval)
682+
!eval_condition(mi, sess, features, eval)
673683
}
674684
sym::target => {
675685
if let Some(features) = features
@@ -690,7 +700,12 @@ pub fn eval_condition(
690700
seg.ident.name = Symbol::intern(&format!("target_{}", seg.ident.name));
691701
}
692702

693-
res & eval_condition(&mi, sess, features, eval)
703+
res & eval_condition(
704+
&ast::NestedMetaItem::MetaItem(mi),
705+
sess,
706+
features,
707+
eval,
708+
)
694709
})
695710
}
696711
_ => {

compiler/rustc_builtin_macros/src/cfg.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ use rustc_ast::token;
66
use rustc_ast::tokenstream::TokenStream;
77
use rustc_errors::PResult;
88
use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacEager, MacroExpanderResult};
9-
use rustc_parse::parser::attr::AllowLeadingUnsafe;
109
use rustc_span::Span;
1110
use {rustc_ast as ast, rustc_attr as attr};
1211

@@ -36,14 +35,18 @@ pub(crate) fn expand_cfg(
3635
})
3736
}
3837

39-
fn parse_cfg<'a>(cx: &ExtCtxt<'a>, span: Span, tts: TokenStream) -> PResult<'a, ast::MetaItem> {
38+
fn parse_cfg<'a>(
39+
cx: &ExtCtxt<'a>,
40+
span: Span,
41+
tts: TokenStream,
42+
) -> PResult<'a, ast::NestedMetaItem> {
4043
let mut p = cx.new_parser_from_tts(tts);
4144

4245
if p.token == token::Eof {
4346
return Err(cx.dcx().create_err(errors::RequiresCfgPattern { span }));
4447
}
4548

46-
let cfg = p.parse_meta_item(AllowLeadingUnsafe::No)?;
49+
let cfg = p.parse_meta_item_inner()?;
4750

4851
let _ = p.eat(&token::Comma);
4952

compiler/rustc_codegen_ssa/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ pub struct NativeLib {
156156
pub kind: NativeLibKind,
157157
pub name: Symbol,
158158
pub filename: Option<Symbol>,
159-
pub cfg: Option<ast::MetaItem>,
159+
pub cfg: Option<ast::NestedMetaItem>,
160160
pub verbatim: bool,
161161
pub dll_imports: Vec<cstore::DllImport>,
162162
}

compiler/rustc_expand/src/config.rs

+7-5
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ use rustc_ast::token::{Delimiter, Token, TokenKind};
55
use rustc_ast::tokenstream::{
66
AttrTokenStream, AttrTokenTree, LazyAttrTokenStream, Spacing, TokenTree,
77
};
8-
use rustc_ast::{self as ast, AttrStyle, Attribute, HasAttrs, HasTokens, MetaItem, NodeId};
8+
use rustc_ast::{
9+
self as ast, AttrStyle, Attribute, HasAttrs, HasTokens, MetaItem, NestedMetaItem, NodeId,
10+
};
911
use rustc_attr as attr;
1012
use rustc_data_structures::flat_map_in_place::FlatMapInPlace;
1113
use rustc_feature::{
@@ -449,7 +451,7 @@ impl<'a> StripUnconfigured<'a> {
449451
}
450452
}
451453

452-
pub fn parse_cfg<'a>(meta_item: &'a MetaItem, sess: &Session) -> Option<&'a MetaItem> {
454+
pub fn parse_cfg<'a>(meta_item: &'a MetaItem, sess: &Session) -> Option<&'a NestedMetaItem> {
453455
let span = meta_item.span;
454456
match meta_item.meta_item_list() {
455457
None => {
@@ -464,9 +466,9 @@ pub fn parse_cfg<'a>(meta_item: &'a MetaItem, sess: &Session) -> Option<&'a Meta
464466
sess.dcx().emit_err(InvalidCfg::MultiplePredicates { span: l.span() });
465467
None
466468
}
467-
Some([single]) => match single.meta_item() {
468-
Some(meta_item) => Some(meta_item),
469-
None => {
469+
Some([single]) => match single.is_meta_item() {
470+
true => Some(single),
471+
false => {
470472
sess.dcx().emit_err(InvalidCfg::PredicateLiteral { span: single.span() });
471473
None
472474
}

compiler/rustc_metadata/src/native_libs.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::ops::ControlFlow;
22
use std::path::{Path, PathBuf};
33

4-
use rustc_ast::{CRATE_NODE_ID, NestedMetaItem};
4+
use rustc_ast::CRATE_NODE_ID;
55
use rustc_attr as attr;
66
use rustc_data_structures::fx::FxHashSet;
77
use rustc_middle::query::LocalCrate;
@@ -304,7 +304,12 @@ impl<'tcx> Collector<'tcx> {
304304
sess.dcx().emit_err(errors::LinkCfgForm { span: item.span() });
305305
continue;
306306
};
307-
let [NestedMetaItem::MetaItem(link_cfg)] = link_cfg else {
307+
let [link_cfg] = link_cfg else {
308+
sess.dcx()
309+
.emit_err(errors::LinkCfgSinglePredicate { span: item.span() });
310+
continue;
311+
};
312+
if !link_cfg.is_meta_item() {
308313
sess.dcx()
309314
.emit_err(errors::LinkCfgSinglePredicate { span: item.span() });
310315
continue;

compiler/rustc_parse/src/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use std::path::Path;
1818

1919
use rustc_ast as ast;
2020
use rustc_ast::tokenstream::TokenStream;
21-
use rustc_ast::{AttrItem, Attribute, MetaItem, token};
21+
use rustc_ast::{AttrItem, Attribute, NestedMetaItem, token};
2222
use rustc_ast_pretty::pprust;
2323
use rustc_data_structures::sync::Lrc;
2424
use rustc_errors::{Diag, FatalError, PResult};
@@ -160,7 +160,7 @@ pub fn fake_token_stream_for_crate(psess: &ParseSess, krate: &ast::Crate) -> Tok
160160
pub fn parse_cfg_attr(
161161
cfg_attr: &Attribute,
162162
psess: &ParseSess,
163-
) -> Option<(MetaItem, Vec<(AttrItem, Span)>)> {
163+
) -> Option<(NestedMetaItem, Vec<(AttrItem, Span)>)> {
164164
const CFG_ATTR_GRAMMAR_HELP: &str = "#[cfg_attr(condition, attribute, other_attribute, ...)]";
165165
const CFG_ATTR_NOTE_REF: &str = "for more information, visit \
166166
<https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg_attr-attribute>";

compiler/rustc_parse/src/parser/attr.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -356,8 +356,10 @@ impl<'a> Parser<'a> {
356356
}
357357

358358
/// Parses `cfg_attr(pred, attr_item_list)` where `attr_item_list` is comma-delimited.
359-
pub fn parse_cfg_attr(&mut self) -> PResult<'a, (ast::MetaItem, Vec<(ast::AttrItem, Span)>)> {
360-
let cfg_predicate = self.parse_meta_item(AllowLeadingUnsafe::No)?;
359+
pub fn parse_cfg_attr(
360+
&mut self,
361+
) -> PResult<'a, (ast::NestedMetaItem, Vec<(ast::AttrItem, Span)>)> {
362+
let cfg_predicate = self.parse_meta_item_inner()?;
361363
self.expect(&token::Comma)?;
362364

363365
// Presumably, the majority of the time there will only be one attr.
@@ -452,7 +454,7 @@ impl<'a> Parser<'a> {
452454
/// ```ebnf
453455
/// MetaItemInner = UNSUFFIXED_LIT | MetaItem ;
454456
/// ```
455-
fn parse_meta_item_inner(&mut self) -> PResult<'a, ast::NestedMetaItem> {
457+
pub fn parse_meta_item_inner(&mut self) -> PResult<'a, ast::NestedMetaItem> {
456458
match self.parse_unsuffixed_meta_item_lit() {
457459
Ok(lit) => return Ok(ast::NestedMetaItem::Lit(lit)),
458460
Err(err) => err.cancel(), // we provide a better error below

compiler/rustc_session/src/cstore.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ pub struct NativeLib {
7272
pub name: Symbol,
7373
/// If packed_bundled_libs enabled, actual filename of library is stored.
7474
pub filename: Option<Symbol>,
75-
pub cfg: Option<ast::MetaItem>,
75+
pub cfg: Option<ast::NestedMetaItem>,
7676
pub foreign_module: Option<DefId>,
7777
pub verbatim: Option<bool>,
7878
pub dll_imports: Vec<DllImport>,

compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::iter;
22
use std::path::PathBuf;
33

4-
use rustc_ast::{AttrArgs, AttrArgsEq, AttrKind, Attribute, MetaItem, NestedMetaItem};
4+
use rustc_ast::{AttrArgs, AttrArgsEq, AttrKind, Attribute, NestedMetaItem};
55
use rustc_data_structures::fx::FxHashMap;
66
use rustc_errors::codes::*;
77
use rustc_errors::{ErrorGuaranteed, struct_span_code_err};
@@ -282,7 +282,7 @@ pub struct OnUnimplementedFormatString {
282282

283283
#[derive(Debug)]
284284
pub struct OnUnimplementedDirective {
285-
pub condition: Option<MetaItem>,
285+
pub condition: Option<NestedMetaItem>,
286286
pub subcommands: Vec<OnUnimplementedDirective>,
287287
pub message: Option<OnUnimplementedFormatString>,
288288
pub label: Option<OnUnimplementedFormatString>,
@@ -414,7 +414,7 @@ impl<'tcx> OnUnimplementedDirective {
414414
let cond = item_iter
415415
.next()
416416
.ok_or_else(|| tcx.dcx().emit_err(EmptyOnClauseInOnUnimplemented { span }))?
417-
.meta_item()
417+
.meta_item_or_bool()
418418
.ok_or_else(|| tcx.dcx().emit_err(InvalidOnClauseInOnUnimplemented { span }))?;
419419
attr::eval_condition(cond, &tcx.sess, Some(tcx.features()), &mut |cfg| {
420420
if let Some(value) = cfg.value
@@ -558,8 +558,8 @@ impl<'tcx> OnUnimplementedDirective {
558558
IgnoredDiagnosticOption::maybe_emit_warning(
559559
tcx,
560560
item_def_id,
561-
directive.condition.as_ref().map(|i| i.span),
562-
aggr.condition.as_ref().map(|i| i.span),
561+
directive.condition.as_ref().map(|i| i.span()),
562+
aggr.condition.as_ref().map(|i| i.span()),
563563
"condition",
564564
);
565565
IgnoredDiagnosticOption::maybe_emit_warning(

tests/ui/macros/cfg.rs

+1-1
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 expected identifier
3+
cfg!(123); //~ ERROR unsupported literal
44
cfg!(foo = 123); //~ ERROR literal in `cfg` predicate value must be a string
55
cfg!(foo, bar); //~ ERROR expected 1 cfg-pattern
66
}

tests/ui/macros/cfg.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ LL | cfg!();
66
|
77
= note: this error originates in the macro `cfg` (in Nightly builds, run with -Z macro-backtrace for more info)
88

9-
error: expected identifier, found `123`
9+
error[E0565]: unsupported literal
1010
--> $DIR/cfg.rs:3:10
1111
|
1212
LL | cfg!(123);
13-
| ^^^ expected identifier
13+
| ^^^
1414

1515
error[E0565]: literal in `cfg` predicate value must be a string
1616
--> $DIR/cfg.rs:4:16

0 commit comments

Comments
 (0)