Skip to content

Correct what makes a configuration option predicate true - #2389

Open
isHeSatoshi wants to merge 1 commit into
rust-lang:masterfrom
isHeSatoshi:cfg-option-name-vs-key-value
Open

isHeSatoshi wants to merge 1 commit into
rust-lang:masterfrom
isHeSatoshi:cfg-option-name-vs-key-value

Conversation

@isHeSatoshi

@isHeSatoshi isHeSatoshi commented Oct 19, 2026 •

Copy link
Copy Markdown

Fixes #2004.

The Reference said:

A configuration option. The predicate is true if the option is set, and false if it is unset.

That reads as a single set/unset bit per key, but a name predicate and a key-value predicate for the same key are independent. @epage said in the issue that this needed some further investigation first, so I checked the actual behaviour before writing anything.

Each row below is the --cfg flags passed to rustc on nightly, and the values are cfg!(foo) and cfg!(foo = "bar") in that same program:

--cfg cfg!(foo) cfg!(foo = "bar")
(none) false false
foo true false
foo="bar" false true
foo="bar" foo="baz" false true
foo foo="bar" true true

Two things follow that are worth being precise about:

  • A key-value predicate does not satisfy the name predicate, and the name does not satisfy any key-value predicate.
  • The last two rows are why the proposed wording "true if the option is set and only a name" would not be accurate on its own: a key can be set as a name and with values at the same time, and then both predicates are true. cfg.option-key-uniqueness already says keys do not need to be unique, which is the same idea one level down.

So the change states the two forms separately and keeps the example inline, since the distinction is easy to get wrong and cheap to check.

cargo run --package=style-check -- src passes. No new links or code blocks are added, so the build and linkcheck jobs are unaffected.

The Reference said a configuration option predicate "is true if the
option is set, and false if it is unset", which reads as a single
set/unset bit per key. That is not how it works: `cfg(foo)` is true only
if `foo` is set as a name, and `cfg(foo = "bar")` is true only if `foo`
is set with that value. Setting a key to a value does not make the name
predicate true, and setting it as a name does not make any key-value
predicate true.

State the two forms separately and keep the example inline, since the
distinction is easy to get wrong and cheap to check.
@rustbot rustbot added the S-waiting-on-review Status: The marked PR is awaiting review from a maintainer label Oct 19, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-review Status: The marked PR is awaiting review from a maintainer

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Conditional compilation makes it sound like #[cfg(foo)] will evaluate to true for --cfg=foo="bar" but it doesn't

2 participants