-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Fix --check-cfg
invocations with zero features
#13011
Conversation
r? @ehuss (rustbot has picked a reviewer for you, use r? to override) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds pretty reasonable to me. Thank you!
@bors r+ |
☀️ Test successful - checks-actions |
To me, this reads as a bug in the design of the syntax if |
The issue here lies before that, |
Update cargo 9 commits in 9765a449d9b7341c2b49b88da41c2268ea599720..71cd3a926f0cf41eeaf9f2a7f2194b2aff85b0f6 2023-11-17 20:58:23 +0000 to 2023-11-20 15:30:57 +0000 - Handle $message_type in JSON diagnostics (rust-lang/cargo#13016) - refactor(toml): Further clean up inheritance (rust-lang/cargo#13000) - Fix `--check-cfg` invocations with zero features (rust-lang/cargo#13011) - chore: bump `cargo-credential-*` crates as e58b84d broke stuff (rust-lang/cargo#13010) - contrib docs: Update now that credential crates are published. (rust-lang/cargo#13006) - Add more resources to the contrib docs. (rust-lang/cargo#13008) - Respect `rust-lang/rust`'s `omit-git-hash` (rust-lang/cargo#12968) - Fix clippy-wrapper test race condition. (rust-lang/cargo#12999) - fix(resolver): Don't do git fetches when updating workspace members (rust-lang/cargo#12975)
To put this in Rust types, does struct EmptyValues;
const EMPTY_VALUES = []; If its like a unit type, then that does feel like special casing.
Is that what we want? Whether there even is a way to define a cfg as an empty array, I suspect being able to do so for As a user, if I get an diagnostic saying that |
It's more like Internally it would be more like
I think so, from the perceptive of
Being able to say: declare a config as expected with all values as unexpected, is not something that is currently possible.
I agree, but Saying that I don't know how to fundamentally improve the situation here. In rust-lang/rust#118071 I propose to add a diagnostic for this case: |
imo the right answer, from the users perspective, is for us to say that a However. since rust-lang/rust#118071 at least provided some help to the user, that is likely sufficient so long as the design allows us to reconsider this in the future. |
I've noted this in #10554 for us to discuss during stabillization |
…mpty, r=petrochenkov Add way to express that no values are expected with check-cfg This PR adds way to express no-values (no values expected) with `--check-cfg` by making empty `values()` no longer mean `values(none())` (internal: `&[None]`) and now be an empty list (internal: `&[]`). ### Context Currently `--check-cfg` has a way to express that _any value is expected_ with `values(any())`, but has no way to do the inverse and say that _no value is expected_. This would be particularly useful for build systems that control a config name and it's values as they could always declare a config name as expected and if in the current state they have values pass them and if not pass an empty list. To give a more concrete example, Cargo `--check-cfg` currently needs to generate: - `--check-cfg=cfg(feature, values(...))` for the case with declared features - and `--check-cfg=cfg()` for the case without any features declared This means that when there are no features declared, users will get an `unexpected config name` but from the point of view of Cargo the config name `feature` is expected, it's just that for now there aren't any values for it. See [Cargo `check_cfg_args` function](https://github.com/rust-lang/cargo/blob/92395d90106b3b61bcb68bcf2069052c93771764/src/cargo/core/compiler/mod.rs#L1263-L1281) for more details. ### De-specializing *empty* `values()` To solve this issue I propose that we "de-specialize" empty `values()` to no longer mean `values(none())` but to actually mean empty set/list. This is one of the last source of confusion for my-self and others with the `--check-cfg` syntax. > The confusing part here is that an empty `values()` currently means the same as `values(none())`, i.e. an expected list of values with the _none_ variant (as in `#[cfg(name)]` where the value is none) instead of meaning an empty set. Before the new `cfg()` syntax, defining the _none_ variant was only possible under certain circumstances, so in rust-lang#111068 I decided to make `values()` to mean the _none_ variant, but it is no longer necessary since rust-lang#119473 which introduced the `none()` syntax. A simplified representation of the proposed "de-specialization" would be: | Syntax | List/set of expected values | |-----------------------------------------|-----------------------------| | `cfg(name)`/`cfg(name, values(none()))` | `&[None]` | | `cfg(name, values())` | `&[]` | Note that I have my-self made the mistake of using an empty `values()` as meaning empty set, see rust-lang/cargo#13011. `@rustbot` label +F-check-cfg r? `@petrochenkov` cc `@epage`
…etrochenkov Add way to express that no values are expected with check-cfg This PR adds way to express no-values (no values expected) with `--check-cfg` by making empty `values()` no longer mean `values(none())` (internal: `&[None]`) and now be an empty list (internal: `&[]`). ### Context Currently `--check-cfg` has a way to express that _any value is expected_ with `values(any())`, but has no way to do the inverse and say that _no value is expected_. This would be particularly useful for build systems that control a config name and it's values as they could always declare a config name as expected and if in the current state they have values pass them and if not pass an empty list. To give a more concrete example, Cargo `--check-cfg` currently needs to generate: - `--check-cfg=cfg(feature, values(...))` for the case with declared features - and `--check-cfg=cfg()` for the case without any features declared This means that when there are no features declared, users will get an `unexpected config name` but from the point of view of Cargo the config name `feature` is expected, it's just that for now there aren't any values for it. See [Cargo `check_cfg_args` function](https://github.com/rust-lang/cargo/blob/92395d90106b3b61bcb68bcf2069052c93771764/src/cargo/core/compiler/mod.rs#L1263-L1281) for more details. ### De-specializing *empty* `values()` To solve this issue I propose that we "de-specialize" empty `values()` to no longer mean `values(none())` but to actually mean empty set/list. This is one of the last source of confusion for my-self and others with the `--check-cfg` syntax. > The confusing part here is that an empty `values()` currently means the same as `values(none())`, i.e. an expected list of values with the _none_ variant (as in `#[cfg(name)]` where the value is none) instead of meaning an empty set. Before the new `cfg()` syntax, defining the _none_ variant was only possible under certain circumstances, so in rust-lang/rust#111068 I decided to make `values()` to mean the _none_ variant, but it is no longer necessary since rust-lang/rust#119473 which introduced the `none()` syntax. A simplified representation of the proposed "de-specialization" would be: | Syntax | List/set of expected values | |-----------------------------------------|-----------------------------| | `cfg(name)`/`cfg(name, values(none()))` | `&[None]` | | `cfg(name, values())` | `&[]` | Note that I have my-self made the mistake of using an empty `values()` as meaning empty set, see rust-lang/cargo#13011. `@rustbot` label +F-check-cfg r? `@petrochenkov` cc `@epage`
Go back to passing an empty `values()` when no features are declared This PR is basically a revert of #13011, which made the `--check-cfg` invocation be `cfg()` when no features are declared instead of `cfg(feature, values())` since it meant declaring that the config `feature` were to be available in this form: `#[cfg(feature)]`, which is not the case. Thankfully after some brainstorming, I [proposed](rust-lang/rust#119930) changing the behavior of empty `values()` in `rustc` to no longer imply the _none_ value and simply create an empty set of expected values. 😃 For Cargo, always using `cfg(feature, values(...))` means that the config `feature` is always expected, regardless of the number of features. This makes the warning better, as it will now always be `unexpected config value` (instead of `unexpected config name`). 🎉 Fixes #13011 (comment) as well as the concern in the [tracking issue](#10554). r? `@epage`
…etrochenkov Add way to express that no values are expected with check-cfg This PR adds way to express no-values (no values expected) with `--check-cfg` by making empty `values()` no longer mean `values(none())` (internal: `&[None]`) and now be an empty list (internal: `&[]`). ### Context Currently `--check-cfg` has a way to express that _any value is expected_ with `values(any())`, but has no way to do the inverse and say that _no value is expected_. This would be particularly useful for build systems that control a config name and it's values as they could always declare a config name as expected and if in the current state they have values pass them and if not pass an empty list. To give a more concrete example, Cargo `--check-cfg` currently needs to generate: - `--check-cfg=cfg(feature, values(...))` for the case with declared features - and `--check-cfg=cfg()` for the case without any features declared This means that when there are no features declared, users will get an `unexpected config name` but from the point of view of Cargo the config name `feature` is expected, it's just that for now there aren't any values for it. See [Cargo `check_cfg_args` function](https://github.com/rust-lang/cargo/blob/92395d90106b3b61bcb68bcf2069052c93771764/src/cargo/core/compiler/mod.rs#L1263-L1281) for more details. ### De-specializing *empty* `values()` To solve this issue I propose that we "de-specialize" empty `values()` to no longer mean `values(none())` but to actually mean empty set/list. This is one of the last source of confusion for my-self and others with the `--check-cfg` syntax. > The confusing part here is that an empty `values()` currently means the same as `values(none())`, i.e. an expected list of values with the _none_ variant (as in `#[cfg(name)]` where the value is none) instead of meaning an empty set. Before the new `cfg()` syntax, defining the _none_ variant was only possible under certain circumstances, so in rust-lang/rust#111068 I decided to make `values()` to mean the _none_ variant, but it is no longer necessary since rust-lang/rust#119473 which introduced the `none()` syntax. A simplified representation of the proposed "de-specialization" would be: | Syntax | List/set of expected values | |-----------------------------------------|-----------------------------| | `cfg(name)`/`cfg(name, values(none()))` | `&[None]` | | `cfg(name, values())` | `&[]` | Note that I have my-self made the mistake of using an empty `values()` as meaning empty set, see rust-lang/cargo#13011. `@rustbot` label +F-check-cfg r? `@petrochenkov` cc `@epage`
…etrochenkov Add way to express that no values are expected with check-cfg This PR adds way to express no-values (no values expected) with `--check-cfg` by making empty `values()` no longer mean `values(none())` (internal: `&[None]`) and now be an empty list (internal: `&[]`). ### Context Currently `--check-cfg` has a way to express that _any value is expected_ with `values(any())`, but has no way to do the inverse and say that _no value is expected_. This would be particularly useful for build systems that control a config name and it's values as they could always declare a config name as expected and if in the current state they have values pass them and if not pass an empty list. To give a more concrete example, Cargo `--check-cfg` currently needs to generate: - `--check-cfg=cfg(feature, values(...))` for the case with declared features - and `--check-cfg=cfg()` for the case without any features declared This means that when there are no features declared, users will get an `unexpected config name` but from the point of view of Cargo the config name `feature` is expected, it's just that for now there aren't any values for it. See [Cargo `check_cfg_args` function](https://github.com/rust-lang/cargo/blob/92395d90106b3b61bcb68bcf2069052c93771764/src/cargo/core/compiler/mod.rs#L1263-L1281) for more details. ### De-specializing *empty* `values()` To solve this issue I propose that we "de-specialize" empty `values()` to no longer mean `values(none())` but to actually mean empty set/list. This is one of the last source of confusion for my-self and others with the `--check-cfg` syntax. > The confusing part here is that an empty `values()` currently means the same as `values(none())`, i.e. an expected list of values with the _none_ variant (as in `#[cfg(name)]` where the value is none) instead of meaning an empty set. Before the new `cfg()` syntax, defining the _none_ variant was only possible under certain circumstances, so in rust-lang/rust#111068 I decided to make `values()` to mean the _none_ variant, but it is no longer necessary since rust-lang/rust#119473 which introduced the `none()` syntax. A simplified representation of the proposed "de-specialization" would be: | Syntax | List/set of expected values | |-----------------------------------------|-----------------------------| | `cfg(name)`/`cfg(name, values(none()))` | `&[None]` | | `cfg(name, values())` | `&[]` | Note that I have my-self made the mistake of using an empty `values()` as meaning empty set, see rust-lang/cargo#13011. `@rustbot` label +F-check-cfg r? `@petrochenkov` cc `@epage`
When generating the
--check-cfg
arguments for-Zcheck-cfg
we currently generatecfg(feature, values())
when there is 0 features. This is wrong since a emptyvalues()
would mean that it's possible to have#[cfg(feature)]
without a feature name which is impossible.We replace this by a simple
cfg()
to still enable well known names and values.Note that currently
rustc
definesfeature
as a well known name with ANY values if it's not overridden by Cargo. I plan on submitting a PR torustc
to removefeature
from being a well known name so that Cargo is the only source of truth.This doesn't block this PR from being merged