Implement boolean lit support in cfg predicates

This commit is contained in:
Urgau 2024-09-19 10:13:14 +02:00
parent 57b9b1f974
commit c99f29b29f
6 changed files with 48 additions and 6 deletions

View File

@ -527,6 +527,16 @@ impl NestedMetaItem {
} }
} }
/// Returns the `MetaItem` if `self` is a `NestedMetaItem::MetaItem` or if it's
/// `NestedMetaItem::Lit(MetaItemLit { kind: LitKind::Bool(_), .. })`.
pub fn meta_item_or_bool(&self) -> Option<&NestedMetaItem> {
match self {
NestedMetaItem::MetaItem(_item) => Some(self),
NestedMetaItem::Lit(MetaItemLit { kind: LitKind::Bool(_), .. }) => Some(self),
_ => None,
}
}
/// Returns the `MetaItem` if `self` is a `NestedMetaItem::MetaItem`. /// Returns the `MetaItem` if `self` is a `NestedMetaItem::MetaItem`.
pub fn meta_item(&self) -> Option<&MetaItem> { pub fn meta_item(&self) -> Option<&MetaItem> {
match self { match self {

View File

@ -603,6 +603,7 @@ pub fn eval_condition(
let cfg = match cfg { let cfg = match cfg {
ast::NestedMetaItem::MetaItem(meta_item) => meta_item, ast::NestedMetaItem::MetaItem(meta_item) => meta_item,
ast::NestedMetaItem::Lit(MetaItemLit { kind: LitKind::Bool(b), .. }) => return *b,
_ => { _ => {
dcx.emit_err(session_diagnostics::UnsupportedLiteral { dcx.emit_err(session_diagnostics::UnsupportedLiteral {
span: cfg.span(), span: cfg.span(),
@ -649,7 +650,7 @@ pub fn eval_condition(
} }
ast::MetaItemKind::List(mis) => { ast::MetaItemKind::List(mis) => {
for mi in mis.iter() { for mi in mis.iter() {
if !mi.is_meta_item() { if mi.meta_item_or_bool().is_none() {
dcx.emit_err(session_diagnostics::UnsupportedLiteral { dcx.emit_err(session_diagnostics::UnsupportedLiteral {
span: mi.span(), span: mi.span(),
reason: UnsupportedLiteralReason::Generic, reason: UnsupportedLiteralReason::Generic,

View File

@ -466,9 +466,9 @@ pub fn parse_cfg<'a>(meta_item: &'a MetaItem, sess: &Session) -> Option<&'a Nest
sess.dcx().emit_err(InvalidCfg::MultiplePredicates { span: l.span() }); sess.dcx().emit_err(InvalidCfg::MultiplePredicates { span: l.span() });
None None
} }
Some([single]) => match single.is_meta_item() { Some([single]) => match single.meta_item_or_bool() {
true => Some(single), Some(meta_item) => Some(meta_item),
false => { None => {
sess.dcx().emit_err(InvalidCfg::PredicateLiteral { span: single.span() }); sess.dcx().emit_err(InvalidCfg::PredicateLiteral { span: single.span() });
None None
} }

View File

@ -309,7 +309,7 @@ impl<'tcx> Collector<'tcx> {
.emit_err(errors::LinkCfgSinglePredicate { span: item.span() }); .emit_err(errors::LinkCfgSinglePredicate { span: item.span() });
continue; continue;
}; };
if !link_cfg.is_meta_item() { let Some(link_cfg) = link_cfg.meta_item_or_bool() else {
sess.dcx() sess.dcx()
.emit_err(errors::LinkCfgSinglePredicate { span: item.span() }); .emit_err(errors::LinkCfgSinglePredicate { span: item.span() });
continue; continue;

View File

@ -413,7 +413,9 @@ impl<'tcx> OnUnimplementedDirective {
} else { } else {
let cond = item_iter let cond = item_iter
.next() .next()
.ok_or_else(|| tcx.dcx().emit_err(EmptyOnClauseInOnUnimplemented { span }))?; .ok_or_else(|| tcx.dcx().emit_err(EmptyOnClauseInOnUnimplemented { span }))?
.meta_item_or_bool()
.ok_or_else(|| tcx.dcx().emit_err(InvalidOnClauseInOnUnimplemented { span }))?;
attr::eval_condition(cond, &tcx.sess, Some(tcx.features()), &mut |cfg| { attr::eval_condition(cond, &tcx.sess, Some(tcx.features()), &mut |cfg| {
if let Some(value) = cfg.value if let Some(value) = cfg.value
&& let Err(guar) = parse_value(value, cfg.span) && let Err(guar) = parse_value(value, cfg.span)

View File

@ -0,0 +1,29 @@
//@ run-pass
#![feature(link_cfg)]
#[cfg(true)]
fn foo() -> bool {
cfg!(true)
}
#[cfg(false)]
fn foo() -> bool {
cfg!(false)
}
#[cfg_attr(true, cfg(false))]
fn foo() {}
#[link(name = "foo", cfg(false))]
extern "C" {}
fn main() {
assert!(foo());
assert!(cfg!(true));
assert!(!cfg!(false));
assert!(cfg!(not(false)));
assert!(cfg!(all(true)));
assert!(cfg!(any(true)));
assert!(!cfg!(not(true)));
}