Skip to content

Commit ae38533

Browse files
committed
Clean up condition evaluation system
1 parent 6534637 commit ae38533

File tree

2 files changed

+71
-67
lines changed

2 files changed

+71
-67
lines changed

compiler/rustc_attr/src/builtin.rs

+64-58
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,15 @@ pub fn find_crate_name(sess: &Session, attrs: &[Attribute]) -> Option<Symbol> {
454454
sess.first_attr_value_str_by_name(attrs, sym::crate_name)
455455
}
456456

457+
#[derive(Clone, Debug)]
458+
pub struct Condition {
459+
pub name: Symbol,
460+
pub name_span: Span,
461+
pub value: Option<Symbol>,
462+
pub value_span: Option<Span>,
463+
pub span: Span,
464+
}
465+
457466
/// Tests if a cfg-pattern matches the cfg set
458467
pub fn cfg_matches(
459468
cfg: &ast::MetaItem,
@@ -462,70 +471,42 @@ pub fn cfg_matches(
462471
features: Option<&Features>,
463472
) -> bool {
464473
eval_condition(cfg, sess, features, &mut |cfg| {
465-
try_gate_cfg(cfg, sess, features);
466-
let error = |span, msg| {
467-
sess.span_diagnostic.span_err(span, msg);
468-
true
469-
};
470-
if cfg.path.segments.len() != 1 {
471-
return error(cfg.path.span, "`cfg` predicate key must be an identifier");
472-
}
473-
match &cfg.kind {
474-
MetaItemKind::List(..) => {
475-
error(cfg.span, "unexpected parentheses after `cfg` predicate key")
476-
}
477-
MetaItemKind::NameValue(lit) if !lit.kind.is_str() => {
478-
handle_errors(
479-
sess,
480-
lit.span,
481-
AttrError::UnsupportedLiteral(
482-
"literal in `cfg` predicate value must be a string",
483-
lit.kind.is_bytestr(),
484-
),
474+
try_gate_cfg(cfg.name, cfg.span, sess, features);
475+
if let Some(names_valid) = &sess.check_config.names_valid {
476+
if !names_valid.contains(&cfg.name) {
477+
sess.buffer_lint_with_diagnostic(
478+
UNEXPECTED_CFGS,
479+
cfg.span,
480+
lint_node_id,
481+
"unexpected `cfg` condition name",
482+
BuiltinLintDiagnostics::UnexpectedCfg((cfg.name, cfg.name_span), None),
485483
);
486-
true
487484
}
488-
MetaItemKind::NameValue(..) | MetaItemKind::Word => {
489-
let ident = cfg.ident().expect("multi-segment cfg predicate");
490-
let name = ident.name;
491-
let value = cfg.value_str();
492-
if let Some(names_valid) = &sess.check_config.names_valid {
493-
if !names_valid.contains(&name) {
494-
sess.buffer_lint_with_diagnostic(
495-
UNEXPECTED_CFGS,
496-
cfg.span,
497-
lint_node_id,
498-
"unexpected `cfg` condition name",
499-
BuiltinLintDiagnostics::UnexpectedCfg((name, ident.span), None),
500-
);
501-
}
502-
}
503-
if let Some(value) = value {
504-
if let Some(values) = &sess.check_config.values_valid.get(&name) {
505-
if !values.contains(&value) {
506-
sess.buffer_lint_with_diagnostic(
507-
UNEXPECTED_CFGS,
508-
cfg.span,
509-
lint_node_id,
510-
"unexpected `cfg` condition value",
511-
BuiltinLintDiagnostics::UnexpectedCfg(
512-
(name, ident.span),
513-
Some((value, cfg.name_value_literal_span().unwrap())),
514-
),
515-
);
516-
}
517-
}
485+
}
486+
if let Some(value) = cfg.value {
487+
if let Some(values) = &sess.check_config.values_valid.get(&cfg.name) {
488+
if !values.contains(&value) {
489+
sess.buffer_lint_with_diagnostic(
490+
UNEXPECTED_CFGS,
491+
cfg.span,
492+
lint_node_id,
493+
"unexpected `cfg` condition value",
494+
BuiltinLintDiagnostics::UnexpectedCfg(
495+
(cfg.name, cfg.name_span),
496+
cfg.value_span.map(|vs| (value, vs)),
497+
),
498+
);
518499
}
519-
sess.config.contains(&(name, value))
520500
}
521501
}
502+
sess.config.contains(&(cfg.name, cfg.value))
522503
})
523504
}
524505

525-
fn try_gate_cfg(cfg: &ast::MetaItem, sess: &ParseSess, features: Option<&Features>) {
526-
let gate = find_gated_cfg(|sym| cfg.has_name(sym));
506+
fn try_gate_cfg(name: Symbol, span: Span, sess: &ParseSess, features: Option<&Features>) {
507+
let gate = find_gated_cfg(|sym| sym == name);
527508
if let (Some(feats), Some(gated_cfg)) = (features, gate) {
528-
gate_cfg(&gated_cfg, cfg.span, sess, feats);
509+
gate_cfg(&gated_cfg, span, sess, feats);
529510
}
530511
}
531512

@@ -563,11 +544,11 @@ pub fn eval_condition(
563544
cfg: &ast::MetaItem,
564545
sess: &ParseSess,
565546
features: Option<&Features>,
566-
eval: &mut impl FnMut(&ast::MetaItem) -> bool,
547+
eval: &mut impl FnMut(Condition) -> bool,
567548
) -> bool {
568549
match cfg.kind {
569550
ast::MetaItemKind::List(ref mis) if cfg.name_or_empty() == sym::version => {
570-
try_gate_cfg(cfg, sess, features);
551+
try_gate_cfg(sym::version, cfg.span, sess, features);
571552
let (min_version, span) = match &mis[..] {
572553
[NestedMetaItem::Literal(Lit { kind: LitKind::Str(sym, ..), span, .. })] => {
573554
(sym, span)
@@ -662,7 +643,32 @@ pub fn eval_condition(
662643
}
663644
}
664645
}
665-
ast::MetaItemKind::Word | ast::MetaItemKind::NameValue(..) => eval(cfg),
646+
ast::MetaItemKind::Word | MetaItemKind::NameValue(..) if cfg.path.segments.len() != 1 => {
647+
sess.span_diagnostic
648+
.span_err(cfg.path.span, "`cfg` predicate key must be an identifier");
649+
true
650+
}
651+
MetaItemKind::NameValue(ref lit) if !lit.kind.is_str() => {
652+
handle_errors(
653+
sess,
654+
lit.span,
655+
AttrError::UnsupportedLiteral(
656+
"literal in `cfg` predicate value must be a string",
657+
lit.kind.is_bytestr(),
658+
),
659+
);
660+
true
661+
}
662+
ast::MetaItemKind::Word | ast::MetaItemKind::NameValue(..) => {
663+
let ident = cfg.ident().expect("multi-segment cfg predicate");
664+
eval(Condition {
665+
name: ident.name,
666+
name_span: ident.span,
667+
value: cfg.value_str(),
668+
value_span: cfg.name_value_literal_span(),
669+
span: cfg.span,
670+
})
671+
}
666672
}
667673
}
668674

compiler/rustc_trait_selection/src/traits/on_unimplemented.rs

+7-9
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,8 @@ impl<'tcx> OnUnimplementedDirective {
8989
None,
9090
)
9191
})?;
92-
attr::eval_condition(cond, &tcx.sess.parse_sess, Some(tcx.features()), &mut |item| {
93-
if let Some(symbol) = item.value_str() && let Err(guar) = parse_value(symbol) {
92+
attr::eval_condition(cond, &tcx.sess.parse_sess, Some(tcx.features()), &mut |cfg| {
93+
if let Some(value) = cfg.value && let Err(guar) = parse_value(value) {
9494
errored = Some(guar);
9595
}
9696
true
@@ -226,14 +226,12 @@ impl<'tcx> OnUnimplementedDirective {
226226
condition,
227227
&tcx.sess.parse_sess,
228228
Some(tcx.features()),
229-
&mut |c| {
230-
c.ident().map_or(false, |ident| {
231-
let value = c.value_str().map(|s| {
232-
OnUnimplementedFormatString(s).format(tcx, trait_ref, &options_map)
233-
});
229+
&mut |cfg| {
230+
let value = cfg.value.map(|v| {
231+
OnUnimplementedFormatString(v).format(tcx, trait_ref, &options_map)
232+
});
234233

235-
options.contains(&(ident.name, value))
236-
})
234+
options.contains(&(cfg.name, value))
237235
},
238236
) {
239237
debug!("evaluate: skipping {:?} due to condition", command);

0 commit comments

Comments
 (0)